From f37ea14969bf85633d3bd29ddf008171a5618855 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 28 Sep 2006 10:52:04 +1000 Subject: [XFS] pass inode to xfs_ioc_space(), simplify some code. There is trivial "inode => vnode => inode" conversion, but only flags and mode of final inode are looked at. Pass original inode instead. SGI-PV: 904196 SGI-Modid: xfs-linux-melb:xfs-kern:26395a Signed-off-by: Alexey Dobriyan Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_ioctl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 6e52a5dd38d..ed8317fba23 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -653,7 +653,7 @@ xfs_attrmulti_by_handle( STATIC int xfs_ioc_space( bhv_desc_t *bdp, - bhv_vnode_t *vp, + struct inode *inode, struct file *filp, int flags, unsigned int cmd, @@ -735,7 +735,7 @@ xfs_ioctl( !capable(CAP_SYS_ADMIN)) return -EPERM; - return xfs_ioc_space(bdp, vp, filp, ioflags, cmd, arg); + return xfs_ioc_space(bdp, inode, filp, ioflags, cmd, arg); case XFS_IOC_DIOINFO: { struct dioattr da; @@ -957,7 +957,7 @@ xfs_ioctl( STATIC int xfs_ioc_space( bhv_desc_t *bdp, - bhv_vnode_t *vp, + struct inode *inode, struct file *filp, int ioflags, unsigned int cmd, @@ -967,13 +967,13 @@ xfs_ioc_space( int attr_flags = 0; int error; - if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND)) + if (inode->i_flags & (S_IMMUTABLE|S_APPEND)) return -XFS_ERROR(EPERM); if (!(filp->f_mode & FMODE_WRITE)) return -XFS_ERROR(EBADF); - if (!VN_ISREG(vp)) + if (!S_ISREG(inode->i_mode)) return -XFS_ERROR(EINVAL); if (copy_from_user(&bf, arg, sizeof(bf))) -- cgit v1.2.3 From f07c225036358038bf8a64f75351f10cdca2fb22 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 10:52:15 +1000 Subject: [XFS] Improve xfsbufd delayed write submission patterns, after blktrace analysis. Under a sequential create+allocate workload, blktrace reported backward writes being issued by xfsbufd, and frequent inappropriate queue unplugs. We now insert at the tail when moving from the delwri lists to the temp lists, which maintains correct ordering, and we avoid unplugging queues deep in the submit paths when we'd shortly do it at a higher level anyway. blktrace now reports much healthier write patterns from xfsbufd for this workload (and likely many others). SGI-PV: 954310 SGI-Modid: xfs-linux-melb:xfs-kern:26396a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_buf.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 2af528dcfb0..f13503508c4 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005 Silicon Graphics, Inc. + * Copyright (c) 2000-2006 Silicon Graphics, Inc. * All Rights Reserved. * * This program is free software; you can redistribute it and/or @@ -1681,6 +1681,7 @@ xfsbufd( xfs_buf_t *bp, *n; struct list_head *dwq = &target->bt_delwrite_queue; spinlock_t *dwlk = &target->bt_delwrite_lock; + int count; current->flags |= PF_MEMALLOC; @@ -1696,6 +1697,7 @@ xfsbufd( schedule_timeout_interruptible( xfs_buf_timer_centisecs * msecs_to_jiffies(10)); + count = 0; age = xfs_buf_age_centisecs * msecs_to_jiffies(10); spin_lock(dwlk); list_for_each_entry_safe(bp, n, dwq, b_list) { @@ -1711,9 +1713,11 @@ xfsbufd( break; } - bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q); + bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q| + _XBF_RUN_QUEUES); bp->b_flags |= XBF_WRITE; - list_move(&bp->b_list, &tmp); + list_move_tail(&bp->b_list, &tmp); + count++; } } spin_unlock(dwlk); @@ -1724,12 +1728,12 @@ xfsbufd( list_del_init(&bp->b_list); xfs_buf_iostrategy(bp); - - blk_run_address_space(target->bt_mapping); } if (as_list_len > 0) purge_addresses(); + if (count) + blk_run_address_space(target->bt_mapping); clear_bit(XBT_FORCE_FLUSH, &target->bt_flags); } while (!kthread_should_stop()); @@ -1767,7 +1771,7 @@ xfs_flush_buftarg( continue; } - list_move(&bp->b_list, &tmp); + list_move_tail(&bp->b_list, &tmp); } spin_unlock(dwlk); @@ -1776,7 +1780,7 @@ xfs_flush_buftarg( */ list_for_each_entry_safe(bp, n, &tmp, b_list) { xfs_buf_lock(bp); - bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q); + bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|_XBF_RUN_QUEUES); bp->b_flags |= XBF_WRITE; if (wait) bp->b_flags &= ~XBF_ASYNC; @@ -1786,6 +1790,9 @@ xfs_flush_buftarg( xfs_buf_iostrategy(bp); } + if (wait) + blk_run_address_space(target->bt_mapping); + /* * Remaining list items must be flushed before returning */ @@ -1797,9 +1804,6 @@ xfs_flush_buftarg( xfs_buf_relse(bp); } - if (wait) - blk_run_address_space(target->bt_mapping); - return pincount; } -- cgit v1.2.3 From 128dabc5e9aa13dfebcad84e6b4ab31078555131 Mon Sep 17 00:00:00 2001 From: Tim Shimmin Date: Thu, 28 Sep 2006 10:55:43 +1000 Subject: [XFS] cleanup the field types of some item format structures SGI-PV: 954365 SGI-Modid: xfs-linux-melb:xfs-kern:26406a Signed-off-by: Tim Shimmin --- fs/xfs/xfs_extfree_item.h | 50 +++++++++++++++++++---------------- fs/xfs/xfs_inode_item.h | 66 ++++++++++++++++++++++++----------------------- 2 files changed, 62 insertions(+), 54 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h index 0ea45edaab0..2f049f63e85 100644 --- a/fs/xfs/xfs_extfree_item.h +++ b/fs/xfs/xfs_extfree_item.h @@ -33,14 +33,16 @@ typedef struct xfs_extent { * conversion routine. */ +#ifndef HAVE_FORMAT32 typedef struct xfs_extent_32 { - xfs_dfsbno_t ext_start; - xfs_extlen_t ext_len; + __uint64_t ext_start; + __uint32_t ext_len; } __attribute__((packed)) xfs_extent_32_t; +#endif typedef struct xfs_extent_64 { - xfs_dfsbno_t ext_start; - xfs_extlen_t ext_len; + __uint64_t ext_start; + __uint32_t ext_len; __uint32_t ext_pad; } xfs_extent_64_t; @@ -50,25 +52,27 @@ typedef struct xfs_extent_64 { * size is given by efi_nextents. */ typedef struct xfs_efi_log_format { - unsigned short efi_type; /* efi log item type */ - unsigned short efi_size; /* size of this item */ - uint efi_nextents; /* # extents to free */ + __uint16_t efi_type; /* efi log item type */ + __uint16_t efi_size; /* size of this item */ + __uint32_t efi_nextents; /* # extents to free */ __uint64_t efi_id; /* efi identifier */ xfs_extent_t efi_extents[1]; /* array of extents to free */ } xfs_efi_log_format_t; +#ifndef HAVE_FORMAT32 typedef struct xfs_efi_log_format_32 { - unsigned short efi_type; /* efi log item type */ - unsigned short efi_size; /* size of this item */ - uint efi_nextents; /* # extents to free */ + __uint16_t efi_type; /* efi log item type */ + __uint16_t efi_size; /* size of this item */ + __uint32_t efi_nextents; /* # extents to free */ __uint64_t efi_id; /* efi identifier */ xfs_extent_32_t efi_extents[1]; /* array of extents to free */ } __attribute__((packed)) xfs_efi_log_format_32_t; +#endif typedef struct xfs_efi_log_format_64 { - unsigned short efi_type; /* efi log item type */ - unsigned short efi_size; /* size of this item */ - uint efi_nextents; /* # extents to free */ + __uint16_t efi_type; /* efi log item type */ + __uint16_t efi_size; /* size of this item */ + __uint32_t efi_nextents; /* # extents to free */ __uint64_t efi_id; /* efi identifier */ xfs_extent_64_t efi_extents[1]; /* array of extents to free */ } xfs_efi_log_format_64_t; @@ -79,25 +83,27 @@ typedef struct xfs_efi_log_format_64 { * size is given by efd_nextents; */ typedef struct xfs_efd_log_format { - unsigned short efd_type; /* efd log item type */ - unsigned short efd_size; /* size of this item */ - uint efd_nextents; /* # of extents freed */ + __uint16_t efd_type; /* efd log item type */ + __uint16_t efd_size; /* size of this item */ + __uint32_t efd_nextents; /* # of extents freed */ __uint64_t efd_efi_id; /* id of corresponding efi */ xfs_extent_t efd_extents[1]; /* array of extents freed */ } xfs_efd_log_format_t; +#ifndef HAVE_FORMAT32 typedef struct xfs_efd_log_format_32 { - unsigned short efd_type; /* efd log item type */ - unsigned short efd_size; /* size of this item */ - uint efd_nextents; /* # of extents freed */ + __uint16_t efd_type; /* efd log item type */ + __uint16_t efd_size; /* size of this item */ + __uint32_t efd_nextents; /* # of extents freed */ __uint64_t efd_efi_id; /* id of corresponding efi */ xfs_extent_32_t efd_extents[1]; /* array of extents freed */ } __attribute__((packed)) xfs_efd_log_format_32_t; +#endif typedef struct xfs_efd_log_format_64 { - unsigned short efd_type; /* efd log item type */ - unsigned short efd_size; /* size of this item */ - uint efd_nextents; /* # of extents freed */ + __uint16_t efd_type; /* efd log item type */ + __uint16_t efd_size; /* size of this item */ + __uint32_t efd_nextents; /* # of extents freed */ __uint64_t efd_efi_id; /* id of corresponding efi */ xfs_extent_64_t efd_extents[1]; /* array of extents freed */ } xfs_efd_log_format_64_t; diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index 5db6cd1b4cf..bfe92ea1795 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -25,52 +25,54 @@ * must be added on to the end. */ typedef struct xfs_inode_log_format { - unsigned short ilf_type; /* inode log item type */ - unsigned short ilf_size; /* size of this item */ - uint ilf_fields; /* flags for fields logged */ - ushort ilf_asize; /* size of attr d/ext/root */ - ushort ilf_dsize; /* size of data/ext/root */ - xfs_ino_t ilf_ino; /* inode number */ + __uint16_t ilf_type; /* inode log item type */ + __uint16_t ilf_size; /* size of this item */ + __uint32_t ilf_fields; /* flags for fields logged */ + __uint16_t ilf_asize; /* size of attr d/ext/root */ + __uint16_t ilf_dsize; /* size of data/ext/root */ + __uint64_t ilf_ino; /* inode number */ union { - xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/ + __uint32_t ilfu_rdev; /* rdev value for dev inode*/ uuid_t ilfu_uuid; /* mount point value */ } ilf_u; __int64_t ilf_blkno; /* blkno of inode buffer */ - int ilf_len; /* len of inode buffer */ - int ilf_boffset; /* off of inode in buffer */ + __int32_t ilf_len; /* len of inode buffer */ + __int32_t ilf_boffset; /* off of inode in buffer */ } xfs_inode_log_format_t; +#ifndef HAVE_FORMAT32 typedef struct xfs_inode_log_format_32 { - unsigned short ilf_type; /* 16: inode log item type */ - unsigned short ilf_size; /* 16: size of this item */ - uint ilf_fields; /* 32: flags for fields logged */ - ushort ilf_asize; /* 32: size of attr d/ext/root */ - ushort ilf_dsize; /* 32: size of data/ext/root */ - xfs_ino_t ilf_ino; /* 64: inode number */ + __uint16_t ilf_type; /* inode log item type */ + __uint16_t ilf_size; /* size of this item */ + __uint32_t ilf_fields; /* flags for fields logged */ + __uint16_t ilf_asize; /* size of attr d/ext/root */ + __uint16_t ilf_dsize; /* size of data/ext/root */ + __uint64_t ilf_ino; /* inode number */ union { - xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/ - uuid_t ilfu_uuid; /* 128: mount point value */ + __uint32_t ilfu_rdev; /* rdev value for dev inode*/ + uuid_t ilfu_uuid; /* mount point value */ } ilf_u; - __int64_t ilf_blkno; /* 64: blkno of inode buffer */ - int ilf_len; /* 32: len of inode buffer */ - int ilf_boffset; /* 32: off of inode in buffer */ + __int64_t ilf_blkno; /* blkno of inode buffer */ + __int32_t ilf_len; /* len of inode buffer */ + __int32_t ilf_boffset; /* off of inode in buffer */ } __attribute__((packed)) xfs_inode_log_format_32_t; +#endif typedef struct xfs_inode_log_format_64 { - unsigned short ilf_type; /* 16: inode log item type */ - unsigned short ilf_size; /* 16: size of this item */ - uint ilf_fields; /* 32: flags for fields logged */ - ushort ilf_asize; /* 32: size of attr d/ext/root */ - ushort ilf_dsize; /* 32: size of data/ext/root */ - __uint32_t ilf_pad; /* 32: pad for 64 bit boundary */ - xfs_ino_t ilf_ino; /* 64: inode number */ + __uint16_t ilf_type; /* inode log item type */ + __uint16_t ilf_size; /* size of this item */ + __uint32_t ilf_fields; /* flags for fields logged */ + __uint16_t ilf_asize; /* size of attr d/ext/root */ + __uint16_t ilf_dsize; /* size of data/ext/root */ + __uint32_t ilf_pad; /* pad for 64 bit boundary */ + __uint64_t ilf_ino; /* inode number */ union { - xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/ - uuid_t ilfu_uuid; /* 128: mount point value */ + __uint32_t ilfu_rdev; /* rdev value for dev inode*/ + uuid_t ilfu_uuid; /* mount point value */ } ilf_u; - __int64_t ilf_blkno; /* 64: blkno of inode buffer */ - int ilf_len; /* 32: len of inode buffer */ - int ilf_boffset; /* 32: off of inode in buffer */ + __int64_t ilf_blkno; /* blkno of inode buffer */ + __int32_t ilf_len; /* len of inode buffer */ + __int32_t ilf_boffset; /* off of inode in buffer */ } xfs_inode_log_format_64_t; /* -- cgit v1.2.3 From 87395deb0b3d174ffcc7f66569764f0715ac5174 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 28 Sep 2006 10:56:01 +1000 Subject: [XFS] move XFS_IOC_GETVERSION to main multiplexer Avoids doing an unnecessary inode to vnode conversion and avoids a memory allocation. SGI-PV: 904196 SGI-Modid: xfs-linux-melb:xfs-kern:26492a Signed-off-by: Alexey Dobriyan Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_ioctl.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index ed8317fba23..a74f854d91e 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -763,6 +763,8 @@ xfs_ioctl( return xfs_ioc_fsgeometry(mp, arg); case XFS_IOC_GETVERSION: + return put_user(inode->i_generation, (int __user *)arg); + case XFS_IOC_GETXFLAGS: case XFS_IOC_SETXFLAGS: case XFS_IOC_FSGETXATTR: @@ -1264,13 +1266,6 @@ xfs_ioc_xattr( break; } - case XFS_IOC_GETVERSION: { - flags = vn_to_inode(vp)->i_generation; - if (copy_to_user(arg, &flags, sizeof(flags))) - error = -EFAULT; - break; - } - default: error = -ENOTTY; break; -- cgit v1.2.3 From 673cdf5c72ff9551df08a71f2ac1a8fe02888e8d Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 10:56:26 +1000 Subject: [XFS] Fix rounding bug in xfs_free_file_space found by sparse checking. SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26551a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_vnodeops.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 23cfa583772..4fbc3e1cac0 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -4272,7 +4272,7 @@ xfs_free_file_space( xfs_mount_t *mp; int nimap; uint resblks; - int rounding; + uint rounding; int rt; xfs_fileoff_t startoffset_fsb; xfs_trans_t *tp; @@ -4313,8 +4313,7 @@ xfs_free_file_space( vn_iowait(vp); /* wait for the completion of any pending DIOs */ } - rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), - (__uint8_t)NBPP); + rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP); ilen = len + (offset & (rounding - 1)); ioffset = offset & ~(rounding - 1); if (ilen & (rounding - 1)) -- cgit v1.2.3 From ed9d88f7b7e6feba457b87ff30249e6c1e139005 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 10:56:43 +1000 Subject: [XFS] Fix sparse warning found when page tracing enabled, due to overloaded gfp_t param. SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26552a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_aops.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 34dcb43a783..7cde30d2939 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -71,7 +71,7 @@ xfs_page_trace( int tag, struct inode *inode, struct page *page, - int mask) + unsigned long pgoff) { xfs_inode_t *ip; bhv_vnode_t *vp = vn_from_inode(inode); @@ -91,7 +91,7 @@ xfs_page_trace( (void *)ip, (void *)inode, (void *)page, - (void *)((unsigned long)mask), + (void *)pgoff, (void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)), (void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)), (void *)((unsigned long)((isize >> 32) & 0xffffffff)), @@ -105,7 +105,7 @@ xfs_page_trace( (void *)NULL); } #else -#define xfs_page_trace(tag, inode, page, mask) +#define xfs_page_trace(tag, inode, page, pgoff) #endif /* @@ -1197,7 +1197,7 @@ xfs_vm_releasepage( .nr_to_write = 1, }; - xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, gfp_mask); + xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, 0); if (!page_has_buffers(page)) return 0; -- cgit v1.2.3 From e21010053a0f11122db728f82ae115f2808752d6 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 28 Sep 2006 10:56:51 +1000 Subject: [XFS] endianess annotation for xfs_agfl_t. Trivial, xfs_agfl_t is always used for ondisk values. SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26553a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_ag.h | 2 +- fs/xfs/xfs_alloc.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index dc2361dd740..9ece7f87ec5 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h @@ -150,7 +150,7 @@ typedef struct xfs_agi { #define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) typedef struct xfs_agfl { - xfs_agblock_t agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ + __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ } xfs_agfl_t; /* diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index d2bbcd882a6..879aa38ddd2 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -2021,7 +2021,7 @@ xfs_alloc_get_freelist( /* * Get the block number and update the data structures. */ - bno = INT_GET(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)], ARCH_CONVERT); + bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]); be32_add(&agf->agf_flfirst, 1); xfs_trans_brelse(tp, agflbp); if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp)) @@ -2108,7 +2108,7 @@ xfs_alloc_put_freelist( { xfs_agf_t *agf; /* a.g. freespace structure */ xfs_agfl_t *agfl; /* a.g. free block array */ - xfs_agblock_t *blockp;/* pointer to array entry */ + __be32 *blockp;/* pointer to array entry */ int error; #ifdef XFS_ALLOC_TRACE static char fname[] = "xfs_alloc_put_freelist"; @@ -2132,7 +2132,7 @@ xfs_alloc_put_freelist( pag->pagf_flcount++; ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; - INT_SET(*blockp, ARCH_CONVERT, bno); + *blockp = cpu_to_be32(bno); TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); xfs_trans_log_buf(tp, agflbp, -- cgit v1.2.3 From 61a258486795ff710cf4518b5a1729c965c32aa0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 28 Sep 2006 10:57:04 +1000 Subject: [XFS] endianess annotations for xfs_inobt_rec_t / xfs_inobt_key_t SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26556a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_btree.c | 6 +++--- fs/xfs/xfs_btree.h | 2 +- fs/xfs/xfs_ialloc.c | 6 +++--- fs/xfs/xfs_ialloc_btree.c | 38 +++++++++++++++++++------------------- fs/xfs/xfs_ialloc_btree.h | 19 ++++++++++++------- fs/xfs/xfs_itable.c | 26 +++++++++++++------------- 6 files changed, 51 insertions(+), 46 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index ee2255bd656..ab6f615d32c 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -170,7 +170,7 @@ xfs_btree_check_key( k1 = ak1; k2 = ak2; - ASSERT(INT_GET(k1->ir_startino, ARCH_CONVERT) < INT_GET(k2->ir_startino, ARCH_CONVERT)); + ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino)); break; } default: @@ -285,8 +285,8 @@ xfs_btree_check_rec( r1 = ar1; r2 = ar2; - ASSERT(INT_GET(r1->ir_startino, ARCH_CONVERT) + XFS_INODES_PER_CHUNK <= - INT_GET(r2->ir_startino, ARCH_CONVERT)); + ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <= + be32_to_cpu(r2->ir_startino)); break; } default: diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 44f1bd98064..2ab156506ac 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h @@ -145,7 +145,7 @@ typedef struct xfs_btree_cur union { xfs_alloc_rec_incore_t a; xfs_bmbt_irec_t b; - xfs_inobt_rec_t i; + xfs_inobt_rec_incore_t i; } bc_rec; /* current insert/search record value */ struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 33164a85aa9..1a5e3ff33ef 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -529,10 +529,10 @@ xfs_dialloc( int offset; /* index of inode in chunk */ xfs_agino_t pagino; /* parent's a.g. relative inode # */ xfs_agnumber_t pagno; /* parent's allocation group number */ - xfs_inobt_rec_t rec; /* inode allocation record */ + xfs_inobt_rec_incore_t rec; /* inode allocation record */ xfs_agnumber_t tagno; /* testing allocation group number */ xfs_btree_cur_t *tcur; /* temp cursor */ - xfs_inobt_rec_t trec; /* temp inode allocation record */ + xfs_inobt_rec_incore_t trec; /* temp inode allocation record */ if (*IO_agbp == NULL) { @@ -945,7 +945,7 @@ xfs_difree( int ilen; /* inodes in an inode cluster */ xfs_mount_t *mp; /* mount structure for filesystem */ int off; /* offset of inode in inode chunk */ - xfs_inobt_rec_t rec; /* btree record */ + xfs_inobt_rec_incore_t rec; /* btree record */ mp = tp->t_mountp; diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index 616eeeb6953..c848141c597 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c @@ -568,7 +568,7 @@ xfs_inobt_insrec( /* * Make a key out of the record data to be inserted, and save it. */ - key.ir_startino = recp->ir_startino; /* INT_: direct copy */ + key.ir_startino = recp->ir_startino; optr = ptr = cur->bc_ptrs[level]; /* * If we're off the left edge, return failure. @@ -641,7 +641,7 @@ xfs_inobt_insrec( return error; #endif ptr = cur->bc_ptrs[level]; - nrec.ir_startino = nkey.ir_startino; /* INT_: direct copy */ + nrec.ir_startino = nkey.ir_startino; } else { /* * Otherwise the insert fails. @@ -950,12 +950,12 @@ xfs_inobt_lookup( xfs_inobt_key_t *kkp; kkp = kkbase + keyno - 1; - startino = INT_GET(kkp->ir_startino, ARCH_CONVERT); + startino = be32_to_cpu(kkp->ir_startino); } else { xfs_inobt_rec_t *krp; krp = krbase + keyno - 1; - startino = INT_GET(krp->ir_startino, ARCH_CONVERT); + startino = be32_to_cpu(krp->ir_startino); } /* * Compute difference to get next direction. @@ -1160,7 +1160,7 @@ xfs_inobt_lshift( } else { memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); - key.ir_startino = rrp->ir_startino; /* INT_: direct copy */ + key.ir_startino = rrp->ir_startino; rkp = &key; } /* @@ -1301,9 +1301,9 @@ xfs_inobt_newroot( kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); /* INT_: struct copy */ } else { rp = XFS_INOBT_REC_ADDR(left, 1, cur); - INT_COPY(kp[0].ir_startino, rp->ir_startino, ARCH_CONVERT); + kp[0].ir_startino = rp->ir_startino; rp = XFS_INOBT_REC_ADDR(right, 1, cur); - INT_COPY(kp[1].ir_startino, rp->ir_startino, ARCH_CONVERT); + kp[1].ir_startino = rp->ir_startino; } xfs_inobt_log_keys(cur, nbp, 1, 2); /* @@ -1420,7 +1420,7 @@ xfs_inobt_rshift( memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); *rrp = *lrp; xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); - key.ir_startino = rrp->ir_startino; /* INT_: direct copy */ + key.ir_startino = rrp->ir_startino; rkp = &key; } /* @@ -1559,7 +1559,7 @@ xfs_inobt_split( rrp = XFS_INOBT_REC_ADDR(right, 1, cur); memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); - keyp->ir_startino = rrp->ir_startino; /* INT_: direct copy */ + keyp->ir_startino = rrp->ir_startino; } /* * Find the left block number by looking in the buffer. @@ -1813,9 +1813,9 @@ xfs_inobt_get_rec( * Point to the record and extract its data. */ rec = XFS_INOBT_REC_ADDR(block, ptr, cur); - *ino = INT_GET(rec->ir_startino, ARCH_CONVERT); - *fcnt = INT_GET(rec->ir_freecount, ARCH_CONVERT); - *free = INT_GET(rec->ir_free, ARCH_CONVERT); + *ino = be32_to_cpu(rec->ir_startino); + *fcnt = be32_to_cpu(rec->ir_freecount); + *free = be64_to_cpu(rec->ir_free); *stat = 1; return 0; } @@ -1930,9 +1930,9 @@ xfs_inobt_insert( level = 0; nbno = NULLAGBLOCK; - INT_SET(nrec.ir_startino, ARCH_CONVERT, cur->bc_rec.i.ir_startino); - INT_SET(nrec.ir_freecount, ARCH_CONVERT, cur->bc_rec.i.ir_freecount); - INT_SET(nrec.ir_free, ARCH_CONVERT, cur->bc_rec.i.ir_free); + nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino); + nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount); + nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free); ncur = (xfs_btree_cur_t *)0; pcur = cur; /* @@ -2060,9 +2060,9 @@ xfs_inobt_update( /* * Fill in the new contents and log them. */ - INT_SET(rp->ir_startino, ARCH_CONVERT, ino); - INT_SET(rp->ir_freecount, ARCH_CONVERT, fcnt); - INT_SET(rp->ir_free, ARCH_CONVERT, free); + rp->ir_startino = cpu_to_be32(ino); + rp->ir_freecount = cpu_to_be32(fcnt); + rp->ir_free = cpu_to_be64(free); xfs_inobt_log_recs(cur, bp, ptr, ptr); /* * Updating first record in leaf. Pass new key value up to our parent. @@ -2070,7 +2070,7 @@ xfs_inobt_update( if (ptr == 1) { xfs_inobt_key_t key; /* key containing [ino] */ - INT_SET(key.ir_startino, ARCH_CONVERT, ino); + key.ir_startino = cpu_to_be32(ino); if ((error = xfs_inobt_updkey(cur, &key, 1))) return error; } diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h index ae3904cb1ee..2c0e49893ff 100644 --- a/fs/xfs/xfs_ialloc_btree.h +++ b/fs/xfs/xfs_ialloc_btree.h @@ -47,19 +47,24 @@ static inline xfs_inofree_t xfs_inobt_maskn(int i, int n) /* * Data record structure */ -typedef struct xfs_inobt_rec -{ +typedef struct xfs_inobt_rec { + __be32 ir_startino; /* starting inode number */ + __be32 ir_freecount; /* count of free inodes (set bits) */ + __be64 ir_free; /* free inode mask */ +} xfs_inobt_rec_t; + +typedef struct xfs_inobt_rec_incore { xfs_agino_t ir_startino; /* starting inode number */ __int32_t ir_freecount; /* count of free inodes (set bits) */ xfs_inofree_t ir_free; /* free inode mask */ -} xfs_inobt_rec_t; +} xfs_inobt_rec_incore_t; + /* * Key structure */ -typedef struct xfs_inobt_key -{ - xfs_agino_t ir_startino; /* starting inode number */ +typedef struct xfs_inobt_key { + __be32 ir_startino; /* starting inode number */ } xfs_inobt_key_t; /* btree pointer type */ @@ -77,7 +82,7 @@ typedef struct xfs_btree_sblock xfs_inobt_block_t; #define XFS_INOBT_IS_FREE(rp,i) \ (((rp)->ir_free & XFS_INOBT_MASK(i)) != 0) #define XFS_INOBT_IS_FREE_DISK(rp,i) \ - ((INT_GET((rp)->ir_free,ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0) + ((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0) #define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i)) #define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i)) diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 46249e4d1fe..7521f301ee5 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -395,9 +395,9 @@ xfs_bulkstat( gcnt++; } gfree |= XFS_INOBT_MASKN(0, chunkidx); - INT_SET(irbp->ir_startino, ARCH_CONVERT, gino); - INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt); - INT_SET(irbp->ir_free, ARCH_CONVERT, gfree); + irbp->ir_startino = cpu_to_be32(gino); + irbp->ir_freecount = cpu_to_be32(gcnt); + irbp->ir_free = cpu_to_be64(gfree); irbp++; agino = gino + XFS_INODES_PER_CHUNK; icount = XFS_INODES_PER_CHUNK - gcnt; @@ -453,9 +453,9 @@ xfs_bulkstat( * If this chunk has any allocated inodes, save it. */ if (gcnt < XFS_INODES_PER_CHUNK) { - INT_SET(irbp->ir_startino, ARCH_CONVERT, gino); - INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt); - INT_SET(irbp->ir_free, ARCH_CONVERT, gfree); + irbp->ir_startino = cpu_to_be32(gino); + irbp->ir_freecount = cpu_to_be32(gcnt); + irbp->ir_free = cpu_to_be64(gfree); irbp++; icount += XFS_INODES_PER_CHUNK - gcnt; } @@ -488,14 +488,14 @@ xfs_bulkstat( * inodes in that cluster. */ for (agbno = XFS_AGINO_TO_AGBNO(mp, - INT_GET(irbp[1].ir_startino, ARCH_CONVERT)), + be32_to_cpu(irbp[1].ir_startino)), chunkidx = 0; chunkidx < XFS_INODES_PER_CHUNK; chunkidx += nicluster, agbno += nbcluster) { if (XFS_INOBT_MASKN(chunkidx, nicluster) & - ~(INT_GET(irbp[1].ir_free, ARCH_CONVERT))) + ~(be64_to_cpu(irbp[1].ir_free))) xfs_btree_reada_bufs(mp, agno, agbno, nbcluster); } @@ -503,9 +503,9 @@ xfs_bulkstat( /* * Now process this chunk of inodes. */ - for (agino = INT_GET(irbp->ir_startino, ARCH_CONVERT), chunkidx = 0, clustidx = 0; + for (agino = be32_to_cpu(irbp->ir_startino), chunkidx = 0, clustidx = 0; ubleft > 0 && - INT_GET(irbp->ir_freecount, ARCH_CONVERT) < XFS_INODES_PER_CHUNK; + be32_to_cpu(irbp->ir_freecount) < XFS_INODES_PER_CHUNK; chunkidx++, clustidx++, agino++) { ASSERT(chunkidx < XFS_INODES_PER_CHUNK); /* @@ -525,7 +525,7 @@ xfs_bulkstat( */ if ((chunkidx & (nicluster - 1)) == 0) { agbno = XFS_AGINO_TO_AGBNO(mp, - INT_GET(irbp->ir_startino, ARCH_CONVERT)) + + be32_to_cpu(irbp->ir_startino)) + ((chunkidx & nimask) >> mp->m_sb.sb_inopblog); @@ -564,13 +564,13 @@ xfs_bulkstat( /* * Skip if this inode is free. */ - if (XFS_INOBT_MASK(chunkidx) & INT_GET(irbp->ir_free, ARCH_CONVERT)) + if (XFS_INOBT_MASK(chunkidx) & be64_to_cpu(irbp->ir_free)) continue; /* * Count used inodes as free so we can tell * when the chunk is used up. */ - INT_MOD(irbp->ir_freecount, ARCH_CONVERT, +1); + be32_add(&irbp->ir_freecount, 1); ino = XFS_AGINO_TO_INO(mp, agno, agino); bno = XFS_AGB_TO_DADDR(mp, agno, agbno); if (flags & BULKSTAT_FG_QUICK) { -- cgit v1.2.3 From c38e5e84dbbeda9a92ea878ec9f6255b519a69e7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 28 Sep 2006 10:57:17 +1000 Subject: [XFS] remove left over INT_ comments in *alloc*.c We can verify endianess handling with sparse now, no need for comments. SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26557a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_alloc_btree.c | 16 ++++++++-------- fs/xfs/xfs_ialloc_btree.c | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 7446556e802..ec0bbd4140e 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -774,7 +774,7 @@ xfs_alloc_insrec( * Now stuff the new record in, bump numrecs * and log the new data. */ - rp[ptr - 1] = *recp; /* INT_: struct copy */ + rp[ptr - 1] = *recp; be16_add(&block->bb_numrecs, 1); xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); #ifdef DEBUG @@ -819,8 +819,8 @@ xfs_alloc_insrec( */ *bnop = nbno; if (nbno != NULLAGBLOCK) { - *recp = nrec; /* INT_: struct copy */ - *curp = ncur; /* INT_: struct copy */ + *recp = nrec; + *curp = ncur; } *stat = 1; return 0; @@ -1229,7 +1229,7 @@ xfs_alloc_lshift( if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level))) return error; #endif - *lpp = *rpp; /* INT_: copy */ + *lpp = *rpp; xfs_alloc_log_ptrs(cur, lbp, nrec, nrec); xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp); } @@ -1406,8 +1406,8 @@ xfs_alloc_newroot( kp = XFS_ALLOC_KEY_ADDR(new, 1, cur); if (be16_to_cpu(left->bb_level) > 0) { - kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); /* INT_: structure copy */ - kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);/* INT_: structure copy */ + kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); + kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur); } else { xfs_alloc_rec_t *rp; /* btree record pointer */ @@ -1527,8 +1527,8 @@ xfs_alloc_rshift( if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level))) return error; #endif - *rkp = *lkp; /* INT_: copy */ - *rpp = *lpp; /* INT_: copy */ + *rkp = *lkp; + *rpp = *lpp; xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1); diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index c848141c597..9b6de4c2c2b 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c @@ -681,7 +681,7 @@ xfs_inobt_insrec( if ((error = xfs_btree_check_sptr(cur, *bnop, level))) return error; #endif - kp[ptr - 1] = key; /* INT_: struct copy */ + kp[ptr - 1] = key; pp[ptr - 1] = cpu_to_be32(*bnop); numrecs++; block->bb_numrecs = cpu_to_be16(numrecs); @@ -698,7 +698,7 @@ xfs_inobt_insrec( * Now stuff the new record in, bump numrecs * and log the new data. */ - rp[ptr - 1] = *recp; /* INT_: struct copy */ + rp[ptr - 1] = *recp; numrecs++; block->bb_numrecs = cpu_to_be16(numrecs); xfs_inobt_log_recs(cur, bp, ptr, numrecs); @@ -731,7 +731,7 @@ xfs_inobt_insrec( */ *bnop = nbno; if (nbno != NULLAGBLOCK) { - *recp = nrec; /* INT_: struct copy */ + *recp = nrec; *curp = ncur; } *stat = 1; @@ -1117,7 +1117,7 @@ xfs_inobt_lshift( if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level))) return error; #endif - *lpp = *rpp; /* INT_: no-change copy */ + *lpp = *rpp; xfs_inobt_log_ptrs(cur, lbp, nrec, nrec); } /* @@ -1297,8 +1297,8 @@ xfs_inobt_newroot( */ kp = XFS_INOBT_KEY_ADDR(new, 1, cur); if (be16_to_cpu(left->bb_level) > 0) { - kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); /* INT_: struct copy */ - kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); /* INT_: struct copy */ + kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); + kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); } else { rp = XFS_INOBT_REC_ADDR(left, 1, cur); kp[0].ir_startino = rp->ir_startino; @@ -1410,8 +1410,8 @@ xfs_inobt_rshift( if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level))) return error; #endif - *rkp = *lkp; /* INT_: no change copy */ - *rpp = *lpp; /* INT_: no change copy */ + *rkp = *lkp; + *rpp = *lpp; xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); } else { -- cgit v1.2.3 From b113bcb83efb411f3cc6c7692fbf933ed01b67d8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 28 Sep 2006 10:57:42 +1000 Subject: [XFS] add xfs_btree_check_lptr_disk variant which handles endian conversion SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26558a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_bmap.c | 2 +- fs/xfs/xfs_bmap_btree.c | 24 ++++++++++++------------ fs/xfs/xfs_btree.h | 3 +++ 3 files changed, 16 insertions(+), 13 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index bf46fae303a..b1efb906dbb 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -3013,7 +3013,7 @@ xfs_bmap_btree_to_extents( pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes); *logflagsp = 0; #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), 1))) + if ((error = xfs_btree_check_lptr_disk(cur, *pp, 1))) return error; #endif cbno = INT_GET(*pp, ARCH_CONVERT); diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 18fb7385d71..270cfe38050 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -382,7 +382,7 @@ xfs_bmbt_delrec( pp = XFS_BMAP_PTR_IADDR(block, 1, cur); #ifdef DEBUG for (i = ptr; i < numrecs; i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); goto error0; } @@ -621,7 +621,7 @@ xfs_bmbt_delrec( rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); #ifdef DEBUG for (i = 0; i < numrrecs; i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); goto error0; } @@ -858,7 +858,7 @@ xfs_bmbt_insrec( pp = XFS_BMAP_PTR_IADDR(block, 1, cur); #ifdef DEBUG for (i = numrecs; i >= ptr; i--) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT), + if ((error = xfs_btree_check_lptr_disk(cur, pp[i - 1], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; @@ -988,7 +988,7 @@ xfs_bmbt_killroot( cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); #ifdef DEBUG for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(cpp[i], ARCH_CONVERT), level - 1))) { + if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -1190,7 +1190,7 @@ xfs_bmbt_lookup( keyno = 1; pp = XFS_BMAP_PTR_IADDR(block, keyno, cur); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -1313,7 +1313,7 @@ xfs_bmbt_lshift( lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur); rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*rpp, ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, *rpp, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -1340,7 +1340,7 @@ xfs_bmbt_lshift( if (level > 0) { #ifdef DEBUG for (i = 0; i < rrecs; i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i + 1], ARCH_CONVERT), + if ((error = xfs_btree_check_lptr_disk(cur, rpp[i + 1], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; @@ -1445,7 +1445,7 @@ xfs_bmbt_rshift( rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); #ifdef DEBUG for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, rpp[i] level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -1454,7 +1454,7 @@ xfs_bmbt_rshift( memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp)); memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*lpp, ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, *lpp, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -1619,7 +1619,7 @@ xfs_bmbt_split( rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); #ifdef DEBUG for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, lpp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -2356,7 +2356,7 @@ xfs_bmbt_newroot( args.firstblock = args.fsbno; if (args.fsbno == NULLFSBLOCK) { #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -2393,7 +2393,7 @@ xfs_bmbt_newroot( cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); #ifdef DEBUG for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { - if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) { + if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 2ab156506ac..8bbcfeba1a9 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h @@ -243,6 +243,9 @@ xfs_btree_check_lptr( xfs_dfsbno_t ptr, /* btree block disk address */ int level); /* btree block level */ +#define xfs_btree_check_lptr_disk(cur, ptr, level) \ + xfs_btree_check_lptr(cur, INT_GET(ptr, ARCH_CONVERT), level) + /* * Checking routine: check that short form block header is ok. */ -- cgit v1.2.3 From 397b5208d5609e2f01b171a34ab690f325253492 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 28 Sep 2006 10:57:52 +1000 Subject: [XFS] endianess annotations for xfs_bmbt_ptr_t/xfs_bmdr_ptr_t SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26559a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_bmap_btree.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index 6478cfa0e53..9137ec7e551 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h @@ -168,8 +168,10 @@ typedef struct xfs_bmbt_key xfs_dfiloff_t br_startoff; /* starting file offset */ } xfs_bmbt_key_t, xfs_bmdr_key_t; -typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */ - /* btree block header type */ +/* btree pointer type */ +typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; + +/* btree block header type */ typedef struct xfs_btree_lblock xfs_bmbt_block_t; #define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp)) -- cgit v1.2.3 From 576039cf3c668d5f8d97dff8a0a5817e8b3a761b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 28 Sep 2006 10:58:06 +1000 Subject: [XFS] endianess annotate XFS_BMAP_BROOT_PTR_ADDR Make sure it returns a __be64 and let the callers use the proper macros. SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26560a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_bmap.c | 61 ++++++++++++++++++++++++------------------------- fs/xfs/xfs_bmap_btree.c | 34 +++++++++++++-------------- fs/xfs/xfs_btree.h | 2 +- 3 files changed, 47 insertions(+), 50 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index b1efb906dbb..76fe9ffb218 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -2999,7 +2999,7 @@ xfs_bmap_btree_to_extents( int error; /* error return value */ xfs_ifork_t *ifp; /* inode fork data */ xfs_mount_t *mp; /* mount point structure */ - xfs_bmbt_ptr_t *pp; /* ptr to block address */ + __be64 *pp; /* ptr to block address */ xfs_bmbt_block_t *rblock;/* root btree block */ ifp = XFS_IFORK_PTR(ip, whichfork); @@ -3011,12 +3011,12 @@ xfs_bmap_btree_to_extents( ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1); mp = ip->i_mount; pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes); + cbno = be64_to_cpu(*pp); *logflagsp = 0; #ifdef DEBUG - if ((error = xfs_btree_check_lptr_disk(cur, *pp, 1))) + if ((error = xfs_btree_check_lptr(cur, cbno, 1))) return error; #endif - cbno = INT_GET(*pp, ARCH_CONVERT); if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF))) return error; @@ -3514,7 +3514,7 @@ xfs_bmap_extents_to_btree( arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp)); pp = XFS_BMAP_PTR_IADDR(block, 1, cur); - INT_SET(*pp, ARCH_CONVERT, args.fsbno); + *pp = cpu_to_be64(args.fsbno); /* * Do all this logging at the end so that * the root is at the right level. @@ -4494,7 +4494,7 @@ xfs_bmap_read_extents( xfs_ifork_t *ifp; /* fork structure */ int level; /* btree level, for checking */ xfs_mount_t *mp; /* file system mount structure */ - xfs_bmbt_ptr_t *pp; /* pointer to block address */ + __be64 *pp; /* pointer to block address */ /* REFERENCED */ xfs_extnum_t room; /* number of entries there's room for */ @@ -4510,10 +4510,10 @@ xfs_bmap_read_extents( level = be16_to_cpu(block->bb_level); ASSERT(level > 0); pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); - ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); - ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); - ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); - bno = INT_GET(*pp, ARCH_CONVERT); + bno = be64_to_cpu(*pp); + ASSERT(bno != NULLDFSBNO); + ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); + ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); /* * Go down the tree until leaf level is reached, following the first * pointer (leftmost) at each level. @@ -4530,10 +4530,8 @@ xfs_bmap_read_extents( break; pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); - XFS_WANT_CORRUPTED_GOTO( - XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), - error0); - bno = INT_GET(*pp, ARCH_CONVERT); + bno = be64_to_cpu(*pp); + XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); xfs_trans_brelse(tp, bp); } /* @@ -6141,7 +6139,7 @@ xfs_check_block( short sz) { int i, j, dmxr; - xfs_bmbt_ptr_t *pp, *thispa; /* pointer to block address */ + __be64 *pp, *thispa; /* pointer to block address */ xfs_bmbt_key_t *prevp, *keyp; ASSERT(be16_to_cpu(block->bb_level) > 0); @@ -6179,11 +6177,10 @@ xfs_check_block( thispa = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, j, dmxr); } - if (INT_GET(*thispa, ARCH_CONVERT) == - INT_GET(*pp, ARCH_CONVERT)) { + if (*thispa == *pp) { cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld", __FUNCTION__, j, i, - INT_GET(*thispa, ARCH_CONVERT)); + (unsigned long long)be64_to_cpu(*thispa)); panic("%s: ptrs are equal in node\n", __FUNCTION__); } @@ -6210,7 +6207,7 @@ xfs_bmap_check_leaf_extents( xfs_ifork_t *ifp; /* fork structure */ int level; /* btree level, for checking */ xfs_mount_t *mp; /* file system mount structure */ - xfs_bmbt_ptr_t *pp; /* pointer to block address */ + __be64 *pp; /* pointer to block address */ xfs_bmbt_rec_t *ep; /* pointer to current extent */ xfs_bmbt_rec_t *lastp; /* pointer to previous extent */ xfs_bmbt_rec_t *nextp; /* pointer to next extent */ @@ -6231,10 +6228,12 @@ xfs_bmap_check_leaf_extents( ASSERT(level > 0); xfs_check_block(block, mp, 1, ifp->if_broot_bytes); pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); - ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); - ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); - ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); - bno = INT_GET(*pp, ARCH_CONVERT); + bno = be64_to_cpu(*pp); + + ASSERT(bno != NULLDFSBNO); + ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); + ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); + /* * Go down the tree until leaf level is reached, following the first * pointer (leftmost) at each level. @@ -6265,8 +6264,8 @@ xfs_bmap_check_leaf_extents( xfs_check_block(block, mp, 0, 0); pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); - XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), error0); - bno = INT_GET(*pp, ARCH_CONVERT); + bno = be64_to_cpu(*pp); + XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); if (bp_release) { bp_release = 0; xfs_trans_brelse(NULL, bp); @@ -6372,7 +6371,7 @@ xfs_bmap_count_blocks( xfs_ifork_t *ifp; /* fork structure */ int level; /* btree level, for checking */ xfs_mount_t *mp; /* file system mount structure */ - xfs_bmbt_ptr_t *pp; /* pointer to block address */ + __be64 *pp; /* pointer to block address */ bno = NULLFSBLOCK; mp = ip->i_mount; @@ -6395,10 +6394,10 @@ xfs_bmap_count_blocks( level = be16_to_cpu(block->bb_level); ASSERT(level > 0); pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes); - ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO); - ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount); - ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks); - bno = INT_GET(*pp, ARCH_CONVERT); + bno = be64_to_cpu(*pp); + ASSERT(bno != NULLDFSBNO); + ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount); + ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks); if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) { XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW, @@ -6425,7 +6424,7 @@ xfs_bmap_count_tree( int error; xfs_buf_t *bp, *nbp; int level = levelin; - xfs_bmbt_ptr_t *pp; + __be64 *pp; xfs_fsblock_t bno = blockno; xfs_fsblock_t nextbno; xfs_bmbt_block_t *block, *nextblock; @@ -6452,7 +6451,7 @@ xfs_bmap_count_tree( /* Dive to the next level */ pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]); - bno = INT_GET(*pp, ARCH_CONVERT); + bno = be64_to_cpu(*pp); if (unlikely((error = xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) { xfs_trans_brelse(tp, bp); diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 270cfe38050..f424cae9685 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -870,14 +870,13 @@ xfs_bmbt_insrec( memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */ (numrecs - ptr + 1) * sizeof(*pp)); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)*bnop, - level))) { + if ((error = xfs_btree_check_lptr(cur, *bnop, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } #endif kp[ptr - 1] = key; - INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop); + pp[ptr - 1] = cpu_to_be64(*bnop); numrecs++; block->bb_numrecs = cpu_to_be16(numrecs); xfs_bmbt_log_keys(cur, bp, ptr, numrecs); @@ -1189,13 +1188,13 @@ xfs_bmbt_lookup( if (diff > 0 && --keyno < 1) keyno = 1; pp = XFS_BMAP_PTR_IADDR(block, keyno, cur); + fsbno = be64_to_cpu(*pp); #ifdef DEBUG - if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) { + if ((error = xfs_btree_check_lptr(cur, fsbno, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } #endif - fsbno = INT_GET(*pp, ARCH_CONVERT); cur->bc_ptrs[level] = keyno; } } @@ -1445,7 +1444,7 @@ xfs_bmbt_rshift( rpp = XFS_BMAP_PTR_IADDR(right, 1, cur); #ifdef DEBUG for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) { - if ((error = xfs_btree_check_lptr_disk(cur, rpp[i] level))) { + if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } @@ -1728,9 +1727,9 @@ xfs_bmdr_to_bmbt( { int dmxr; xfs_bmbt_key_t *fkp; - xfs_bmbt_ptr_t *fpp; + __be64 *fpp; xfs_bmbt_key_t *tkp; - xfs_bmbt_ptr_t *tpp; + __be64 *tpp; rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); rblock->bb_level = dblock->bb_level; @@ -1745,7 +1744,7 @@ xfs_bmdr_to_bmbt( tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen); dmxr = be16_to_cpu(dblock->bb_numrecs); memcpy(tkp, fkp, sizeof(*fkp) * dmxr); - memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */ + memcpy(tpp, fpp, sizeof(*fpp) * dmxr); } /* @@ -1805,7 +1804,7 @@ xfs_bmbt_decrement( tp = cur->bc_tp; mp = cur->bc_mp; for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) { - fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT); + fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur)); if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, XFS_BMAP_BTREE_REF))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); @@ -2135,7 +2134,7 @@ xfs_bmbt_increment( tp = cur->bc_tp; mp = cur->bc_mp; for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) { - fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT); + fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur)); if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, XFS_BMAP_BTREE_REF))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); @@ -2361,7 +2360,7 @@ xfs_bmbt_newroot( return error; } #endif - args.fsbno = INT_GET(*pp, ARCH_CONVERT); + args.fsbno = be64_to_cpu(*pp); args.type = XFS_ALLOCTYPE_START_BNO; } else args.type = XFS_ALLOCTYPE_NEAR_BNO; @@ -2401,13 +2400,12 @@ xfs_bmbt_newroot( #endif memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp)); #ifdef DEBUG - if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)args.fsbno, - level))) { + if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; } #endif - INT_SET(*pp, ARCH_CONVERT, args.fsbno); + *pp = cpu_to_be64(args.fsbno); xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs), cur->bc_private.b.whichfork); xfs_btree_setbuf(cur, level, bp); @@ -2681,9 +2679,9 @@ xfs_bmbt_to_bmdr( { int dmxr; xfs_bmbt_key_t *fkp; - xfs_bmbt_ptr_t *fpp; + __be64 *fpp; xfs_bmbt_key_t *tkp; - xfs_bmbt_ptr_t *tpp; + __be64 *tpp; ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC); ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO); @@ -2698,7 +2696,7 @@ xfs_bmbt_to_bmdr( tpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr); dmxr = be16_to_cpu(dblock->bb_numrecs); memcpy(tkp, fkp, sizeof(*fkp) * dmxr); - memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */ + memcpy(tpp, fpp, sizeof(*fpp) * dmxr); } /* diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 8bbcfeba1a9..892b06c5426 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h @@ -244,7 +244,7 @@ xfs_btree_check_lptr( int level); /* btree block level */ #define xfs_btree_check_lptr_disk(cur, ptr, level) \ - xfs_btree_check_lptr(cur, INT_GET(ptr, ARCH_CONVERT), level) + xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level) /* * Checking routine: check that short form block header is ok. -- cgit v1.2.3 From 8801bb99e4425b9a778b355153ab3254bb431d92 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 28 Sep 2006 10:58:17 +1000 Subject: [XFS] endianess annotations for xfs_bmbt_key Trivial as there are no incore users. SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26561a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_bmap.c | 2 +- fs/xfs/xfs_bmap_btree.c | 49 +++++++++++++++++++++---------------------------- fs/xfs/xfs_bmap_btree.h | 5 ++--- fs/xfs/xfs_btree.c | 2 +- 4 files changed, 25 insertions(+), 33 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 76fe9ffb218..e28146fe046 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -3512,7 +3512,7 @@ xfs_bmap_extents_to_btree( */ kp = XFS_BMAP_KEY_IADDR(block, 1, cur); arp = XFS_BMAP_REC_IADDR(ablock, 1, cur); - INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp)); + kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp)); pp = XFS_BMAP_PTR_IADDR(block, 1, cur); *pp = cpu_to_be64(args.fsbno); /* diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index f424cae9685..aab8e3f06ac 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -58,7 +58,7 @@ STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int); STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *); STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *); STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *, - xfs_bmbt_key_t *, xfs_btree_cur_t **, int *); + __uint64_t *, xfs_btree_cur_t **, int *); STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int); @@ -192,16 +192,11 @@ xfs_bmbt_trace_argifk( xfs_btree_cur_t *cur, int i, xfs_fsblock_t f, - xfs_bmbt_key_t *k, + xfs_dfiloff_t o, int line) { - xfs_dfsbno_t d; - xfs_dfiloff_t o; - - d = (xfs_dfsbno_t)f; - o = INT_GET(k->br_startoff, ARCH_CONVERT); xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line, - i, d >> 32, (int)d, o >> 32, + i, (xfs_dfsbno_t)f >> 32, (int)f, o >> 32, (int)o, 0, 0, 0, 0, 0, 0); } @@ -248,7 +243,7 @@ xfs_bmbt_trace_argik( { xfs_dfiloff_t o; - o = INT_GET(k->br_startoff, ARCH_CONVERT); + o = be64_to_cpu(k->br_startoff); xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line, i, o >> 32, (int)o, 0, 0, 0, 0, 0, @@ -286,8 +281,8 @@ xfs_bmbt_trace_cursor( xfs_bmbt_trace_argfffi(fname, c, o, b, i, j, __LINE__) #define XFS_BMBT_TRACE_ARGI(c,i) \ xfs_bmbt_trace_argi(fname, c, i, __LINE__) -#define XFS_BMBT_TRACE_ARGIFK(c,i,f,k) \ - xfs_bmbt_trace_argifk(fname, c, i, f, k, __LINE__) +#define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) \ + xfs_bmbt_trace_argifk(fname, c, i, f, s, __LINE__) #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \ xfs_bmbt_trace_argifr(fname, c, i, f, r, __LINE__) #define XFS_BMBT_TRACE_ARGIK(c,i,k) \ @@ -299,7 +294,7 @@ xfs_bmbt_trace_cursor( #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) #define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) #define XFS_BMBT_TRACE_ARGI(c,i) -#define XFS_BMBT_TRACE_ARGIFK(c,i,f,k) +#define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) #define XFS_BMBT_TRACE_ARGIK(c,i,k) #define XFS_BMBT_TRACE_CURSOR(c,s) @@ -404,7 +399,8 @@ xfs_bmbt_delrec( xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1); } if (ptr == 1) { - INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(rp)); + key.br_startoff = + cpu_to_be64(xfs_bmbt_disk_get_startoff(rp)); kp = &key; } } @@ -748,7 +744,7 @@ xfs_bmbt_insrec( int logflags; /* inode logging flags */ xfs_fsblock_t nbno; /* new block number */ struct xfs_btree_cur *ncur; /* new btree cursor */ - xfs_bmbt_key_t nkey; /* new btree key value */ + __uint64_t startoff; /* new btree key value */ xfs_bmbt_rec_t nrec; /* new record count */ int optr; /* old key/record index */ xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */ @@ -760,8 +756,7 @@ xfs_bmbt_insrec( XFS_BMBT_TRACE_CURSOR(cur, ENTRY); XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp); ncur = (xfs_btree_cur_t *)0; - INT_SET(key.br_startoff, ARCH_CONVERT, - xfs_bmbt_disk_get_startoff(recp)); + key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp)); optr = ptr = cur->bc_ptrs[level]; if (ptr == 0) { XFS_BMBT_TRACE_CURSOR(cur, EXIT); @@ -820,7 +815,7 @@ xfs_bmbt_insrec( optr = ptr = cur->bc_ptrs[level]; } else { if ((error = xfs_bmbt_split(cur, level, - &nbno, &nkey, &ncur, + &nbno, &startoff, &ncur, &i))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); @@ -840,7 +835,7 @@ xfs_bmbt_insrec( #endif ptr = cur->bc_ptrs[level]; xfs_bmbt_disk_set_allf(&nrec, - nkey.br_startoff, 0, 0, + startoff, 0, 0, XFS_EXT_NORM); } else { XFS_BMBT_TRACE_CURSOR(cur, @@ -1169,7 +1164,7 @@ xfs_bmbt_lookup( keyno = (low + high) >> 1; if (level > 0) { kkp = kkbase + keyno - 1; - startoff = INT_GET(kkp->br_startoff, ARCH_CONVERT); + startoff = be64_to_cpu(kkp->br_startoff); } else { krp = krbase + keyno - 1; startoff = xfs_bmbt_disk_get_startoff(krp); @@ -1353,8 +1348,7 @@ xfs_bmbt_lshift( } else { memmove(rrp, rrp + 1, rrecs * sizeof(*rrp)); xfs_bmbt_log_recs(cur, rbp, 1, rrecs); - INT_SET(key.br_startoff, ARCH_CONVERT, - xfs_bmbt_disk_get_startoff(rrp)); + key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp)); rkp = &key; } if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) { @@ -1468,8 +1462,7 @@ xfs_bmbt_rshift( memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); *rrp = *lrp; xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1); - INT_SET(key.br_startoff, ARCH_CONVERT, - xfs_bmbt_disk_get_startoff(rrp)); + key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp)); rkp = &key; } be16_add(&left->bb_numrecs, -1); @@ -1534,7 +1527,7 @@ xfs_bmbt_split( xfs_btree_cur_t *cur, int level, xfs_fsblock_t *bnop, - xfs_bmbt_key_t *keyp, + __uint64_t *startoff, xfs_btree_cur_t **curp, int *stat) /* success/failure */ { @@ -1559,7 +1552,7 @@ xfs_bmbt_split( xfs_bmbt_rec_t *rrp; /* right record pointer */ XFS_BMBT_TRACE_CURSOR(cur, ENTRY); - XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, keyp); + XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, *startoff); args.tp = cur->bc_tp; args.mp = cur->bc_mp; lbp = cur->bc_bufs[level]; @@ -1628,13 +1621,13 @@ xfs_bmbt_split( memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp)); xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); - keyp->br_startoff = INT_GET(rkp->br_startoff, ARCH_CONVERT); + *startoff = be64_to_cpu(rkp->br_startoff); } else { lrp = XFS_BMAP_REC_IADDR(left, i, cur); rrp = XFS_BMAP_REC_IADDR(right, 1, cur); memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp)); xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs)); - keyp->br_startoff = xfs_bmbt_disk_get_startoff(rrp); + *startoff = xfs_bmbt_disk_get_startoff(rrp); } be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs))); right->bb_rightsib = left->bb_rightsib; @@ -2738,7 +2731,7 @@ xfs_bmbt_update( XFS_BMBT_TRACE_CURSOR(cur, EXIT); return 0; } - INT_SET(key.br_startoff, ARCH_CONVERT, off); + key.br_startoff = cpu_to_be64(off); if ((error = xfs_bmbt_updkey(cur, &key, 1))) { XFS_BMBT_TRACE_CURSOR(cur, ERROR); return error; diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index 9137ec7e551..49539de9525 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h @@ -163,9 +163,8 @@ typedef struct xfs_bmbt_irec /* * Key structure for non-leaf levels of the tree. */ -typedef struct xfs_bmbt_key -{ - xfs_dfiloff_t br_startoff; /* starting file offset */ +typedef struct xfs_bmbt_key { + __be64 br_startoff; /* starting file offset */ } xfs_bmbt_key_t, xfs_bmdr_key_t; /* btree pointer type */ diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index ab6f615d32c..aeb87ca69fc 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -161,7 +161,7 @@ xfs_btree_check_key( k1 = ak1; k2 = ak2; - ASSERT(INT_GET(k1->br_startoff, ARCH_CONVERT) < INT_GET(k2->br_startoff, ARCH_CONVERT)); + ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff)); break; } case XFS_BTNUM_INO: { -- cgit v1.2.3 From 1121b219bf3fe6d1bd1d1f7618cc5e0c409fabb4 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 10:58:40 +1000 Subject: [XFS] use NULL for pointer initialisation instead of zero-cast-to-ptr SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26562a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_alloc_btree.c | 8 ++++---- fs/xfs/xfs_bmap_btree.c | 10 +++++----- fs/xfs/xfs_ialloc.c | 4 ++-- fs/xfs/xfs_ialloc_btree.c | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index ec0bbd4140e..500a1d75403 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -670,7 +670,7 @@ xfs_alloc_insrec( } #endif nbno = NULLAGBLOCK; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; /* * If the block is full, we can't insert the new entry until we * make the block un-full. @@ -981,7 +981,7 @@ xfs_alloc_lookup( */ bp = cur->bc_bufs[level]; if (bp && XFS_BUF_ADDR(bp) != d) - bp = (xfs_buf_t *)0; + bp = NULL; if (!bp) { /* * Need to get a new buffer. Read it, then @@ -2044,7 +2044,7 @@ xfs_alloc_insert( nbno = NULLAGBLOCK; nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock); nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount); - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; pcur = cur; /* * Loop going up the tree, starting at the leaf level. @@ -2076,7 +2076,7 @@ xfs_alloc_insert( */ if (ncur) { pcur = ncur; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; } } while (nbno != NULLAGBLOCK); *stat = i; diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index aab8e3f06ac..a7b835bf870 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -352,7 +352,7 @@ xfs_bmbt_delrec( XFS_BMBT_TRACE_CURSOR(cur, ENTRY); XFS_BMBT_TRACE_ARGI(cur, level); ptr = cur->bc_ptrs[level]; - tcur = (xfs_btree_cur_t *)0; + tcur = NULL; if (ptr == 0) { XFS_BMBT_TRACE_CURSOR(cur, EXIT); *stat = 0; @@ -755,7 +755,7 @@ xfs_bmbt_insrec( ASSERT(level < cur->bc_nlevels); XFS_BMBT_TRACE_CURSOR(cur, ENTRY); XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp); - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp)); optr = ptr = cur->bc_ptrs[level]; if (ptr == 0) { @@ -1126,7 +1126,7 @@ xfs_bmbt_lookup( d = XFS_FSB_TO_DADDR(mp, fsbno); bp = cur->bc_bufs[level]; if (bp && XFS_BUF_ADDR(bp) != d) - bp = (xfs_buf_t *)0; + bp = NULL; if (!bp) { if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp, XFS_BMAP_BTREE_REF))) { @@ -2170,7 +2170,7 @@ xfs_bmbt_insert( level = 0; nbno = NULLFSBLOCK; xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b); - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; pcur = cur; do { if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur, @@ -2197,7 +2197,7 @@ xfs_bmbt_insert( } if (ncur) { pcur = ncur; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; } } while (nbno != NULLFSBLOCK); XFS_BMBT_TRACE_CURSOR(cur, EXIT); diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 1a5e3ff33ef..76813d608de 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -458,7 +458,7 @@ nextag: */ if (XFS_FORCED_SHUTDOWN(mp)) { up_read(&mp->m_peraglock); - return (xfs_buf_t *)0; + return NULL; } agno++; if (agno >= agcount) @@ -466,7 +466,7 @@ nextag: if (agno == pagno) { if (flags == 0) { up_read(&mp->m_peraglock); - return (xfs_buf_t *)0; + return NULL; } flags = 0; } diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index 9b6de4c2c2b..8cdeeaf8632 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c @@ -600,7 +600,7 @@ xfs_inobt_insrec( } #endif nbno = NULLAGBLOCK; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; /* * If the block is full, we can't insert the new entry until we * make the block un-full. @@ -878,7 +878,7 @@ xfs_inobt_lookup( */ bp = cur->bc_bufs[level]; if (bp && XFS_BUF_ADDR(bp) != d) - bp = (xfs_buf_t *)0; + bp = NULL; if (!bp) { /* * Need to get a new buffer. Read it, then @@ -1933,7 +1933,7 @@ xfs_inobt_insert( nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino); nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount); nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free); - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; pcur = cur; /* * Loop going up the tree, starting at the leaf level. @@ -1965,7 +1965,7 @@ xfs_inobt_insert( */ if (ncur) { pcur = ncur; - ncur = (xfs_btree_cur_t *)0; + ncur = NULL; } } while (nbno != NULLAGBLOCK); *stat = i; -- cgit v1.2.3 From fe48cae9ed979d2ac14080c837d793c4f6bfaa82 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 28 Sep 2006 10:58:52 +1000 Subject: [XFS] remove bhv_lookup, _range version works aswell and has more useful semantics. SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26563a Signed-off-by: Christoph Hellwig Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_vnode.h | 2 -- fs/xfs/xfs_behavior.c | 20 -------------------- fs/xfs/xfs_behavior.h | 2 -- fs/xfs/xfs_mount.h | 3 ++- 4 files changed, 2 insertions(+), 25 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index c42b3221b20..515f5fdea57 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -85,8 +85,6 @@ typedef enum { #define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh))) #define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name) #define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp) -#define vn_bhv_lookup(bhp,ops) bhv_lookup(bhp,ops) -#define vn_bhv_lookup_unlocked(bhp,ops) bhv_lookup_unlocked(bhp,ops) /* * Vnode to Linux inode mapping. diff --git a/fs/xfs/xfs_behavior.c b/fs/xfs/xfs_behavior.c index f4fe3715a80..0dc17219d41 100644 --- a/fs/xfs/xfs_behavior.c +++ b/fs/xfs/xfs_behavior.c @@ -109,26 +109,6 @@ bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp) prev->bd_next = bdp->bd_next; /* remove from after prev */ } -/* - * Look for a specific ops vector on the specified behavior chain. - * Return the associated behavior descriptor. Or NULL, if not found. - */ -bhv_desc_t * -bhv_lookup(bhv_head_t *bhp, void *ops) -{ - bhv_desc_t *curdesc; - - for (curdesc = bhp->bh_first; - curdesc != NULL; - curdesc = curdesc->bd_next) { - - if (curdesc->bd_ops == ops) - return curdesc; - } - - return NULL; -} - /* * Looks for the first behavior within a specified range of positions. * Return the associated behavior descriptor. Or NULL, if none found. diff --git a/fs/xfs/xfs_behavior.h b/fs/xfs/xfs_behavior.h index 6e6e56fb352..e7ca1fed955 100644 --- a/fs/xfs/xfs_behavior.h +++ b/fs/xfs/xfs_behavior.h @@ -176,12 +176,10 @@ extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *); * Behavior module prototypes. */ extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp); -extern bhv_desc_t * bhv_lookup(bhv_head_t *bhp, void *ops); extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high); extern bhv_desc_t * bhv_base(bhv_head_t *bhp); /* No bhv locking on Linux */ -#define bhv_lookup_unlocked bhv_lookup #define bhv_base_unlocked bhv_base #endif /* __XFS_BEHAVIOR_H__ */ diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index b2bd4be4200..3091c44f29e 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -541,7 +541,8 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp) #define XFS_VFSTOM(vfs) xfs_vfstom(vfs) static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs) { - return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops)); + return XFS_BHVTOM(bhv_lookup_range(VFS_BHVHEAD(vfs), + VFS_POSITION_XFS, VFS_POSITION_XFS)); } #define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d) -- cgit v1.2.3 From 29b6d22b011d83dac8ca5b7d26f766ae598abbbd Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 10:59:06 +1000 Subject: [XFS] remove accidentally reintroduced vfs unmount flag, unneeded in current kernels SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26564a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_vfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h index 91fc2c4b335..da255bdf526 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.h +++ b/fs/xfs/linux-2.6/xfs_vfs.h @@ -79,7 +79,7 @@ typedef enum { #define VFS_RDONLY 0x0001 /* read-only vfs */ #define VFS_GRPID 0x0002 /* group-ID assigned from directory */ #define VFS_DMI 0x0004 /* filesystem has the DMI enabled */ -#define VFS_UMOUNT 0x0008 /* unmount in progress */ +/* ---- VFS_UMOUNT ---- 0x0008 -- unneeded, fixed via kthread APIs */ #define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */ #define VFS_END 0x0010 /* max flag */ -- cgit v1.2.3 From 69e23b9a5e7430ced667d8b699330e370c202f28 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:01:22 +1000 Subject: [XFS] Update XFS for i_blksize removal from generic inode structure SGI-PV: 954366 SGI-Modid: xfs-linux-melb:xfs-kern:26565a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_iops.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 22e3b714f62..3ba814ae3bb 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -623,12 +623,27 @@ xfs_vn_getattr( { struct inode *inode = dentry->d_inode; bhv_vnode_t *vp = vn_from_inode(inode); - int error = 0; + bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT }; + int error; - if (unlikely(vp->v_flag & VMODIFIED)) - error = vn_revalidate(vp); - if (!error) - generic_fillattr(inode, stat); + error = bhv_vop_getattr(vp, &vattr, ATTR_LAZY, NULL); + if (likely(!error)) { + stat->size = i_size_read(inode); + stat->dev = inode->i_sb->s_dev; + stat->rdev = (vattr.va_rdev == 0) ? 0 : + MKDEV(sysv_major(vattr.va_rdev) & 0x1ff, + sysv_minor(vattr.va_rdev)); + stat->mode = vattr.va_mode; + stat->nlink = vattr.va_nlink; + stat->uid = vattr.va_uid; + stat->gid = vattr.va_gid; + stat->ino = vattr.va_nodeid; + stat->atime = vattr.va_atime; + stat->mtime = vattr.va_mtime; + stat->ctime = vattr.va_ctime; + stat->blocks = vattr.va_nblocks; + stat->blksize = vattr.va_blocksize; + } return -error; } -- cgit v1.2.3 From 726801ba067410a1d38518823f2c253a087f6c6f Mon Sep 17 00:00:00 2001 From: Tim Shimmin Date: Thu, 28 Sep 2006 11:01:37 +1000 Subject: [XFS] Add EA list callbacks for xfs kernel use. Cleanup some namespace code. SGI-PV: 954372 SGI-Modid: xfs-linux-melb:xfs-kern:26583a Signed-off-by: Tim Shimmin --- fs/xfs/xfs_attr.c | 181 +++++++++++++++++++------ fs/xfs/xfs_attr.h | 8 +- fs/xfs/xfs_attr_leaf.c | 351 ++++++++++++++++++++++--------------------------- fs/xfs/xfs_attr_leaf.h | 41 ++++-- 4 files changed, 334 insertions(+), 247 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 1a210104327..9ada7bdbae5 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c @@ -91,7 +91,6 @@ STATIC int xfs_attr_refillstate(xfs_da_state_t *state); /* * Routines to manipulate out-of-line attribute values. */ -STATIC int xfs_attr_rmtval_get(xfs_da_args_t *args); STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args); STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args); @@ -180,7 +179,7 @@ xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp, return(error); } -STATIC int +int xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen, char *value, int valuelen, int flags) { @@ -440,7 +439,7 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f * Generic handler routine to remove a name from an attribute list. * Transitions attribute list from Btree to shortform as necessary. */ -STATIC int +int xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags) { xfs_da_args_t args; @@ -591,6 +590,110 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred) return xfs_attr_remove_int(dp, name, namelen, flags); } +int /* error */ +xfs_attr_list_int(xfs_attr_list_context_t *context) +{ + int error; + xfs_inode_t *dp = context->dp; + + /* + * Decide on what work routines to call based on the inode size. + */ + if (XFS_IFORK_Q(dp) == 0 || + (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && + dp->i_d.di_anextents == 0)) { + error = 0; + } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { + error = xfs_attr_shortform_list(context); + } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { + error = xfs_attr_leaf_list(context); + } else { + error = xfs_attr_node_list(context); + } + return error; +} + +#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \ + (((struct attrlist_ent *) 0)->a_name - (char *) 0) +#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \ + ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \ + & ~(sizeof(u_int32_t)-1)) + +/* + * Format an attribute and copy it out to the user's buffer. + * Take care to check values and protect against them changing later, + * we may be reading them directly out of a user buffer. + */ +/*ARGSUSED*/ +STATIC int +xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp, + char *name, int namelen, + int valuelen, char *value) +{ + attrlist_ent_t *aep; + int arraytop; + + ASSERT(!(context->flags & ATTR_KERNOVAL)); + ASSERT(context->count >= 0); + ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); + ASSERT(context->firstu >= sizeof(*context->alist)); + ASSERT(context->firstu <= context->bufsize); + + arraytop = sizeof(*context->alist) + + context->count * sizeof(context->alist->al_offset[0]); + context->firstu -= ATTR_ENTSIZE(namelen); + if (context->firstu < arraytop) { + xfs_attr_trace_l_c("buffer full", context); + context->alist->al_more = 1; + context->seen_enough = 1; + return 1; + } + + aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]); + aep->a_valuelen = valuelen; + memcpy(aep->a_name, name, namelen); + aep->a_name[ namelen ] = 0; + context->alist->al_offset[ context->count++ ] = context->firstu; + context->alist->al_count = context->count; + xfs_attr_trace_l_c("add", context); + return 0; +} + +STATIC int +xfs_attr_kern_list(xfs_attr_list_context_t *context, attrnames_t *namesp, + char *name, int namelen, + int valuelen, char *value) +{ + char *offset; + int arraytop; + + ASSERT(context->count >= 0); + + arraytop = context->count + namesp->attr_namelen + namelen + 1; + if (arraytop > context->firstu) { + context->count = -1; /* insufficient space */ + return 1; + } + offset = (char *)context->alist + context->count; + strncpy(offset, namesp->attr_name, namesp->attr_namelen); + offset += namesp->attr_namelen; + strncpy(offset, name, namelen); /* real name */ + offset += namelen; + *offset = '\0'; + context->count += namesp->attr_namelen + namelen + 1; + return 0; +} + +/*ARGSUSED*/ +STATIC int +xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp, + char *name, int namelen, + int valuelen, char *value) +{ + context->count += namesp->attr_namelen + namelen + 1; + return 0; +} + /* * Generate a list of extended attribute names and optionally * also value lengths. Positive return value follows the XFS @@ -615,13 +718,13 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, return(XFS_ERROR(EINVAL)); if ((cursor->initted == 0) && (cursor->hashval || cursor->blkno || cursor->offset)) - return(XFS_ERROR(EINVAL)); + return XFS_ERROR(EINVAL); /* * Check for a properly aligned buffer. */ if (((long)buffer) & (sizeof(int)-1)) - return(XFS_ERROR(EFAULT)); + return XFS_ERROR(EFAULT); if (flags & ATTR_KERNOVAL) bufsize = 0; @@ -634,53 +737,47 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags, context.dupcnt = 0; context.resynch = 1; context.flags = flags; - if (!(flags & ATTR_KERNAMELS)) { + context.seen_enough = 0; + context.alist = (attrlist_t *)buffer; + context.put_value = 0; + + if (flags & ATTR_KERNAMELS) { + context.bufsize = bufsize; + context.firstu = context.bufsize; + if (flags & ATTR_KERNOVAL) + context.put_listent = xfs_attr_kern_list_sizes; + else + context.put_listent = xfs_attr_kern_list; + } else { context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */ context.firstu = context.bufsize; - context.alist = (attrlist_t *)buffer; context.alist->al_count = 0; context.alist->al_more = 0; context.alist->al_offset[0] = context.bufsize; - } - else { - context.bufsize = bufsize; - context.firstu = context.bufsize; - context.alist = (attrlist_t *)buffer; + context.put_listent = xfs_attr_put_listent; } if (XFS_FORCED_SHUTDOWN(dp->i_mount)) - return (EIO); + return EIO; xfs_ilock(dp, XFS_ILOCK_SHARED); - /* - * Decide on what work routines to call based on the inode size. - */ xfs_attr_trace_l_c("syscall start", &context); - if (XFS_IFORK_Q(dp) == 0 || - (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && - dp->i_d.di_anextents == 0)) { - error = 0; - } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { - error = xfs_attr_shortform_list(&context); - } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { - error = xfs_attr_leaf_list(&context); - } else { - error = xfs_attr_node_list(&context); - } + + error = xfs_attr_list_int(&context); + xfs_iunlock(dp, XFS_ILOCK_SHARED); xfs_attr_trace_l_c("syscall end", &context); - if (!(context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS))) { - ASSERT(error >= 0); - } - else { /* must return negated buffer size or the error */ + if (context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS)) { + /* must return negated buffer size or the error */ if (context.count < 0) error = XFS_ERROR(ERANGE); else error = -context.count; - } + } else + ASSERT(error >= 0); - return(error); + return error; } int /* error */ @@ -1122,19 +1219,19 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context) context->cursor->blkno = 0; error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK); if (error) - return(error); + return XFS_ERROR(error); ASSERT(bp != NULL); leaf = bp->data; if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) { XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW, context->dp->i_mount, leaf); xfs_da_brelse(NULL, bp); - return(XFS_ERROR(EFSCORRUPTED)); + return XFS_ERROR(EFSCORRUPTED); } - (void)xfs_attr_leaf_list_int(bp, context); + error = xfs_attr_leaf_list_int(bp, context); xfs_da_brelse(NULL, bp); - return(0); + return XFS_ERROR(error); } @@ -1858,8 +1955,12 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) return(XFS_ERROR(EFSCORRUPTED)); } error = xfs_attr_leaf_list_int(bp, context); - if (error || !leaf->hdr.info.forw) - break; /* not really an error, buffer full or EOF */ + if (error) { + xfs_da_brelse(NULL, bp); + return error; + } + if (context->seen_enough || leaf->hdr.info.forw == 0) + break; cursor->blkno = be32_to_cpu(leaf->hdr.info.forw); xfs_da_brelse(NULL, bp); error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1, @@ -1886,7 +1987,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context) * Read the value associated with an attribute from the out-of-line buffer * that we stored it in. */ -STATIC int +int xfs_attr_rmtval_get(xfs_da_args_t *args) { xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE]; diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index 981633f6c07..783977d3ea7 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h @@ -37,6 +37,7 @@ struct cred; struct bhv_vnode; +struct xfs_attr_list_context; typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int); typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int); @@ -160,13 +161,16 @@ struct xfs_da_args; */ int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *); int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *); +int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int); int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *); -int xfs_attr_list(bhv_desc_t *, char *, int, int, - struct attrlist_cursor_kern *, struct cred *); +int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int); +int xfs_attr_list(bhv_desc_t *, char *, int, int, struct attrlist_cursor_kern *, struct cred *); +int xfs_attr_list_int(struct xfs_attr_list_context *); int xfs_attr_inactive(struct xfs_inode *dp); int xfs_attr_shortform_getvalue(struct xfs_da_args *); int xfs_attr_fetch(struct xfs_inode *, const char *, int, char *, int *, int, struct cred *); +int xfs_attr_rmtval_get(struct xfs_da_args *args); #endif /* __XFS_ATTR_H__ */ diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 9455051f012..9719bbef122 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -89,9 +89,46 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf, int dst_start, int move_count, xfs_mount_t *mp); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); -STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context, - attrnames_t *, char *name, int namelen, - int valuelen); + +/*======================================================================== + * Namespace helper routines + *========================================================================*/ + +STATIC inline attrnames_t * +xfs_attr_flags_namesp(int flags) +{ + return ((flags & XFS_ATTR_SECURE) ? &attr_secure: + ((flags & XFS_ATTR_ROOT) ? &attr_trusted : &attr_user)); +} + +/* + * If namespace bits don't match return 0. + * If all match then return 1. + */ +STATIC inline int +xfs_attr_namesp_match(int arg_flags, int ondisk_flags) +{ + return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); +} + +/* + * If namespace bits don't match and we don't have an override for it + * then return 0. + * If all match or are overridable then return 1. + */ +STATIC inline int +xfs_attr_namesp_match_overrides(int arg_flags, int ondisk_flags) +{ + if (((arg_flags & ATTR_SECURE) == 0) != + ((ondisk_flags & XFS_ATTR_SECURE) == 0) && + !(arg_flags & ATTR_KERNORMALS)) + return 0; + if (((arg_flags & ATTR_ROOT) == 0) != + ((ondisk_flags & XFS_ATTR_ROOT) == 0) && + !(arg_flags & ATTR_KERNROOTLS)) + return 0; + return 1; +} /*======================================================================== @@ -228,11 +265,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((sfe->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((sfe->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; ASSERT(0); #endif @@ -246,8 +279,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff) sfe->namelen = args->namelen; sfe->valuelen = args->valuelen; - sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : - ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0); + sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); memcpy(sfe->nameval, args->name, args->namelen); memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen); sf->hdr.count++; @@ -282,11 +314,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args) continue; if (memcmp(sfe->nameval, args->name, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((sfe->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((sfe->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; break; } @@ -363,11 +391,7 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((sfe->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((sfe->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; return(XFS_ERROR(EEXIST)); } @@ -394,11 +418,7 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args) continue; if (memcmp(args->name, sfe->nameval, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((sfe->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((sfe->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, sfe->flags)) continue; if (args->flags & ATTR_KERNOVAL) { args->valuelen = sfe->valuelen; @@ -485,8 +505,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) nargs.valuelen = sfe->valuelen; nargs.hashval = xfs_da_hashname((char *)sfe->nameval, sfe->namelen); - nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : - ((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); + nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == ENOATTR); error = xfs_attr_leaf_add(bp, &nargs); @@ -520,6 +539,10 @@ xfs_attr_shortform_compare(const void *a, const void *b) } } + +#define XFS_ISRESET_CURSOR(cursor) \ + (!((cursor)->initted) && !((cursor)->hashval) && \ + !((cursor)->blkno) && !((cursor)->offset)) /* * Copy out entries of shortform attribute lists for attr_list(). * Shortform attribute lists are not stored in hashval sorted order. @@ -537,6 +560,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) xfs_attr_sf_entry_t *sfe; xfs_inode_t *dp; int sbsize, nsbuf, count, i; + int error; ASSERT(context != NULL); dp = context->dp; @@ -552,46 +576,51 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) xfs_attr_trace_l_c("sf start", context); /* - * If the buffer is large enough, do not bother with sorting. + * If the buffer is large enough and the cursor is at the start, + * do not bother with sorting since we will return everything in + * one buffer and another call using the cursor won't need to be + * made. * Note the generous fudge factor of 16 overhead bytes per entry. + * If bufsize is zero then put_listent must be a search function + * and can just scan through what we have. */ - if ((dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize) { + if (context->bufsize == 0 || + (XFS_ISRESET_CURSOR(cursor) && + (dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) { for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { attrnames_t *namesp; - if (((context->flags & ATTR_SECURE) != 0) != - ((sfe->flags & XFS_ATTR_SECURE) != 0) && - !(context->flags & ATTR_KERNORMALS)) { - sfe = XFS_ATTR_SF_NEXTENTRY(sfe); - continue; - } - if (((context->flags & ATTR_ROOT) != 0) != - ((sfe->flags & XFS_ATTR_ROOT) != 0) && - !(context->flags & ATTR_KERNROOTLS)) { + if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) { sfe = XFS_ATTR_SF_NEXTENTRY(sfe); continue; } - namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure: - ((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : - &attr_user); - if (context->flags & ATTR_KERNOVAL) { - ASSERT(context->flags & ATTR_KERNAMELS); - context->count += namesp->attr_namelen + - sfe->namelen + 1; - } - else { - if (xfs_attr_put_listent(context, namesp, - (char *)sfe->nameval, - (int)sfe->namelen, - (int)sfe->valuelen)) - break; - } + namesp = xfs_attr_flags_namesp(sfe->flags); + error = context->put_listent(context, + namesp, + (char *)sfe->nameval, + (int)sfe->namelen, + (int)sfe->valuelen, + (char*)&sfe->nameval[sfe->namelen]); + + /* + * Either search callback finished early or + * didn't fit it all in the buffer after all. + */ + if (context->seen_enough) + break; + + if (error) + return error; sfe = XFS_ATTR_SF_NEXTENTRY(sfe); } xfs_attr_trace_l_c("sf big-gulp", context); return(0); } + /* do no more for a search callback */ + if (context->bufsize == 0) + return 0; + /* * It didn't all fit, so we have to sort everything on hashval. */ @@ -614,15 +643,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) kmem_free(sbuf, sbsize); return XFS_ERROR(EFSCORRUPTED); } - if (((context->flags & ATTR_SECURE) != 0) != - ((sfe->flags & XFS_ATTR_SECURE) != 0) && - !(context->flags & ATTR_KERNORMALS)) { - sfe = XFS_ATTR_SF_NEXTENTRY(sfe); - continue; - } - if (((context->flags & ATTR_ROOT) != 0) != - ((sfe->flags & XFS_ATTR_ROOT) != 0) && - !(context->flags & ATTR_KERNROOTLS)) { + if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) { sfe = XFS_ATTR_SF_NEXTENTRY(sfe); continue; } @@ -671,24 +692,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) for ( ; i < nsbuf; i++, sbp++) { attrnames_t *namesp; - namesp = (sbp->flags & XFS_ATTR_SECURE) ? &attr_secure : - ((sbp->flags & XFS_ATTR_ROOT) ? &attr_trusted : - &attr_user); + namesp = xfs_attr_flags_namesp(sbp->flags); if (cursor->hashval != sbp->hash) { cursor->hashval = sbp->hash; cursor->offset = 0; } - if (context->flags & ATTR_KERNOVAL) { - ASSERT(context->flags & ATTR_KERNAMELS); - context->count += namesp->attr_namelen + - sbp->namelen + 1; - } else { - if (xfs_attr_put_listent(context, namesp, - sbp->name, sbp->namelen, - sbp->valuelen)) - break; - } + error = context->put_listent(context, + namesp, + sbp->name, + sbp->namelen, + sbp->valuelen, + &sbp->name[sbp->namelen]); + if (error) + return error; + if (context->seen_enough) + break; cursor->offset++; } @@ -810,8 +829,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff) nargs.value = (char *)&name_loc->nameval[nargs.namelen]; nargs.valuelen = be16_to_cpu(name_loc->valuelen); nargs.hashval = be32_to_cpu(entry->hashval); - nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE : - ((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0); + nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags); xfs_attr_shortform_add(&nargs, forkoff); } error = 0; @@ -1098,8 +1116,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex) be16_to_cpu(map->size)); entry->hashval = cpu_to_be32(args->hashval); entry->flags = tmp ? XFS_ATTR_LOCAL : 0; - entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE : - ((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0); + entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags); if (args->rename) { entry->flags |= XFS_ATTR_INCOMPLETE; if ((args->blkno2 == args->blkno) && @@ -1926,7 +1943,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) else break; } - ASSERT((probe >= 0) && + ASSERT((probe >= 0) && (!leaf->hdr.count || (probe < be16_to_cpu(leaf->hdr.count)))); ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); @@ -1971,14 +1988,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe); if (name_loc->namelen != args->namelen) continue; - if (memcmp(args->name, (char *)name_loc->nameval, - args->namelen) != 0) + if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((entry->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((entry->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, entry->flags)) continue; args->index = probe; return(XFS_ERROR(EEXIST)); @@ -1989,11 +2001,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args) if (memcmp(args->name, (char *)name_rmt->name, args->namelen) != 0) continue; - if (((args->flags & ATTR_SECURE) != 0) != - ((entry->flags & XFS_ATTR_SECURE) != 0)) - continue; - if (((args->flags & ATTR_ROOT) != 0) != - ((entry->flags & XFS_ATTR_ROOT) != 0)) + if (!xfs_attr_namesp_match(args->flags, entry->flags)) continue; args->index = probe; args->rmtblkno = be32_to_cpu(name_rmt->valueblk); @@ -2312,8 +2320,6 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) attrlist_cursor_kern_t *cursor; xfs_attr_leafblock_t *leaf; xfs_attr_leaf_entry_t *entry; - xfs_attr_leaf_name_local_t *name_loc; - xfs_attr_leaf_name_remote_t *name_rmt; int retval, i; ASSERT(bp != NULL); @@ -2355,9 +2361,8 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) * We have found our place, start copying out the new attributes. */ retval = 0; - for ( ; (i < be16_to_cpu(leaf->hdr.count)) - && (retval == 0); entry++, i++) { - attrnames_t *namesp; + for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) { + attrnames_t *namesp; if (be32_to_cpu(entry->hashval) != cursor->hashval) { cursor->hashval = be32_to_cpu(entry->hashval); @@ -2366,115 +2371,69 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) if (entry->flags & XFS_ATTR_INCOMPLETE) continue; /* skip incomplete entries */ - if (((context->flags & ATTR_SECURE) != 0) != - ((entry->flags & XFS_ATTR_SECURE) != 0) && - !(context->flags & ATTR_KERNORMALS)) - continue; /* skip non-matching entries */ - if (((context->flags & ATTR_ROOT) != 0) != - ((entry->flags & XFS_ATTR_ROOT) != 0) && - !(context->flags & ATTR_KERNROOTLS)) - continue; /* skip non-matching entries */ - - namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure : - ((entry->flags & XFS_ATTR_ROOT) ? &attr_trusted : - &attr_user); + if (!xfs_attr_namesp_match_overrides(context->flags, entry->flags)) + continue; + + namesp = xfs_attr_flags_namesp(entry->flags); if (entry->flags & XFS_ATTR_LOCAL) { - name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); - if (context->flags & ATTR_KERNOVAL) { - ASSERT(context->flags & ATTR_KERNAMELS); - context->count += namesp->attr_namelen + - (int)name_loc->namelen + 1; - } else { - retval = xfs_attr_put_listent(context, namesp, - (char *)name_loc->nameval, - (int)name_loc->namelen, - be16_to_cpu(name_loc->valuelen)); - } + xfs_attr_leaf_name_local_t *name_loc = + XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); + + retval = context->put_listent(context, + namesp, + (char *)name_loc->nameval, + (int)name_loc->namelen, + be16_to_cpu(name_loc->valuelen), + (char *)&name_loc->nameval[name_loc->namelen]); + if (retval) + return retval; } else { - name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); - if (context->flags & ATTR_KERNOVAL) { - ASSERT(context->flags & ATTR_KERNAMELS); - context->count += namesp->attr_namelen + - (int)name_rmt->namelen + 1; - } else { - retval = xfs_attr_put_listent(context, namesp, - (char *)name_rmt->name, - (int)name_rmt->namelen, - be32_to_cpu(name_rmt->valuelen)); + xfs_attr_leaf_name_remote_t *name_rmt = + XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); + + int valuelen = be32_to_cpu(name_rmt->valuelen); + + if (context->put_value) { + xfs_da_args_t args; + + memset((char *)&args, 0, sizeof(args)); + args.dp = context->dp; + args.whichfork = XFS_ATTR_FORK; + args.valuelen = valuelen; + args.value = kmem_alloc(valuelen, KM_SLEEP); + args.rmtblkno = be32_to_cpu(name_rmt->valueblk); + args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen); + retval = xfs_attr_rmtval_get(&args); + if (retval) + return retval; + retval = context->put_listent(context, + namesp, + (char *)name_rmt->name, + (int)name_rmt->namelen, + valuelen, + (char*)args.value); + kmem_free(args.value, valuelen); } + else { + retval = context->put_listent(context, + namesp, + (char *)name_rmt->name, + (int)name_rmt->namelen, + valuelen, + NULL); + } + if (retval) + return retval; } - if (retval == 0) { - cursor->offset++; - } + if (context->seen_enough) + break; + cursor->offset++; } xfs_attr_trace_l_cl("blk end", context, leaf); return(retval); } -#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \ - (((struct attrlist_ent *) 0)->a_name - (char *) 0) -#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \ - ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \ - & ~(sizeof(u_int32_t)-1)) - -/* - * Format an attribute and copy it out to the user's buffer. - * Take care to check values and protect against them changing later, - * we may be reading them directly out of a user buffer. - */ -/*ARGSUSED*/ -STATIC int -xfs_attr_put_listent(xfs_attr_list_context_t *context, - attrnames_t *namesp, char *name, int namelen, int valuelen) -{ - attrlist_ent_t *aep; - int arraytop; - - ASSERT(!(context->flags & ATTR_KERNOVAL)); - if (context->flags & ATTR_KERNAMELS) { - char *offset; - - ASSERT(context->count >= 0); - - arraytop = context->count + namesp->attr_namelen + namelen + 1; - if (arraytop > context->firstu) { - context->count = -1; /* insufficient space */ - return(1); - } - offset = (char *)context->alist + context->count; - strncpy(offset, namesp->attr_name, namesp->attr_namelen); - offset += namesp->attr_namelen; - strncpy(offset, name, namelen); /* real name */ - offset += namelen; - *offset = '\0'; - context->count += namesp->attr_namelen + namelen + 1; - return(0); - } - - ASSERT(context->count >= 0); - ASSERT(context->count < (ATTR_MAX_VALUELEN/8)); - ASSERT(context->firstu >= sizeof(*context->alist)); - ASSERT(context->firstu <= context->bufsize); - - arraytop = sizeof(*context->alist) + - context->count * sizeof(context->alist->al_offset[0]); - context->firstu -= ATTR_ENTSIZE(namelen); - if (context->firstu < arraytop) { - xfs_attr_trace_l_c("buffer full", context); - context->alist->al_more = 1; - return(1); - } - - aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]); - aep->a_valuelen = valuelen; - memcpy(aep->a_name, name, namelen); - aep->a_name[ namelen ] = 0; - context->alist->al_offset[ context->count++ ] = context->firstu; - context->alist->al_count = context->count; - xfs_attr_trace_l_c("add", context); - return(0); -} /*======================================================================== * Manage the INCOMPLETE flag in a leaf entry diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h index 51c3ee156b2..040f732ce1e 100644 --- a/fs/xfs/xfs_attr_leaf.h +++ b/fs/xfs/xfs_attr_leaf.h @@ -129,6 +129,19 @@ typedef struct xfs_attr_leafblock { #define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT) #define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT) +/* + * Conversion macros for converting namespace bits from argument flags + * to ondisk flags. + */ +#define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE) +#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE) +#define XFS_ATTR_NSP_ONDISK(flags) ((flags) & XFS_ATTR_NSP_ONDISK_MASK) +#define XFS_ATTR_NSP_ARGS(flags) ((flags) & XFS_ATTR_NSP_ARGS_MASK) +#define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\ + ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0)) +#define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\ + ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0)) + /* * Alignment for namelist and valuelist entries (since they are mixed * there can be only one alignment value) @@ -196,16 +209,26 @@ static inline int xfs_attr_leaf_entsize_local_max(int bsize) * Structure used to pass context around among the routines. *========================================================================*/ + +struct xfs_attr_list_context; + +typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, struct attrnames *, + char *, int, int, char *); + typedef struct xfs_attr_list_context { - struct xfs_inode *dp; /* inode */ - struct attrlist_cursor_kern *cursor;/* position in list */ - struct attrlist *alist; /* output buffer */ - int count; /* num used entries */ - int dupcnt; /* count dup hashvals seen */ - int bufsize;/* total buffer size */ - int firstu; /* first used byte in buffer */ - int flags; /* from VOP call */ - int resynch;/* T/F: resynch with cursor */ + struct xfs_inode *dp; /* inode */ + struct attrlist_cursor_kern *cursor; /* position in list */ + struct attrlist *alist; /* output buffer */ + int seen_enough; /* T/F: seen enough of list? */ + int count; /* num used entries */ + int dupcnt; /* count dup hashvals seen */ + int bufsize; /* total buffer size */ + int firstu; /* first used byte in buffer */ + int flags; /* from VOP call */ + int resynch; /* T/F: resynch with cursor */ + int put_value; /* T/F: need value for listent */ + put_listent_func_t put_listent; /* list output fmt function */ + int index; /* index into output buffer */ } xfs_attr_list_context_t; /* -- cgit v1.2.3 From 8b56f083c2a6bd0a88271225f0bcf1d81db20d3c Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:01:46 +1000 Subject: [XFS] Rework DMAPI bulkstat calls in such a way that we can directly extract inline attributes out of the bulkstat buffer (for that case), rather than using an (extremely expensive for large icount filesystems) iget for fetching attrs. SGI-PV: 944409 SGI-Modid: xfs-linux-melb:xfs-kern:26602a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_itable.c | 65 ++++++++++++++++++++++++++++++++++++++++++++--------- fs/xfs/xfs_itable.h | 11 ++++----- 2 files changed, 61 insertions(+), 15 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 7521f301ee5..305a9d0436f 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -252,6 +252,46 @@ xfs_bulkstat_one( return error; } +/* + * Test to see whether we can use the ondisk inode directly, based + * on the given bulkstat flags, filling in dipp accordingly. + * Returns zero if the inode is dodgey. + */ +STATIC int +xfs_bulkstat_use_dinode( + xfs_mount_t *mp, + int flags, + xfs_buf_t *bp, + int clustidx, + xfs_dinode_t **dipp) +{ + xfs_dinode_t *dip; + unsigned int aformat; + + *dipp = NULL; + if (!bp || (flags & BULKSTAT_FG_IGET)) + return 1; + dip = (xfs_dinode_t *) + xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog); + if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC || + !XFS_DINODE_GOOD_VERSION( + INT_GET(dip->di_core.di_version, ARCH_CONVERT))) + return 0; + if (flags & BULKSTAT_FG_QUICK) { + *dipp = dip; + return 1; + } + /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ + aformat = INT_GET(dip->di_core.di_aformat, ARCH_CONVERT); + if ((XFS_CFORK_Q(&dip->di_core) == 0) || + (aformat == XFS_DINODE_FMT_LOCAL) || + (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) { + *dipp = dip; + return 1; + } + return 1; +} + /* * Return stat information in bulk (by-inode) for the filesystem. */ @@ -529,7 +569,8 @@ xfs_bulkstat( ((chunkidx & nimask) >> mp->m_sb.sb_inopblog); - if (flags & BULKSTAT_FG_QUICK) { + if (flags & (BULKSTAT_FG_QUICK | + BULKSTAT_FG_INLINE)) { ino = XFS_AGINO_TO_INO(mp, agno, agino); bno = XFS_AGB_TO_DADDR(mp, agno, @@ -573,21 +614,25 @@ xfs_bulkstat( be32_add(&irbp->ir_freecount, 1); ino = XFS_AGINO_TO_INO(mp, agno, agino); bno = XFS_AGB_TO_DADDR(mp, agno, agbno); - if (flags & BULKSTAT_FG_QUICK) { - dip = (xfs_dinode_t *)xfs_buf_offset(bp, - (clustidx << mp->m_sb.sb_inodelog)); - - if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) - != XFS_DINODE_MAGIC - || !XFS_DINODE_GOOD_VERSION( - INT_GET(dip->di_core.di_version, ARCH_CONVERT))) - continue; + if (!xfs_bulkstat_use_dinode(mp, flags, bp, + clustidx, &dip)) + continue; + /* + * If we need to do an iget, cannot hold bp. + * Drop it, until starting the next cluster. + */ + if ((flags & BULKSTAT_FG_INLINE) && !dip) { + if (bp) + xfs_buf_relse(bp); + bp = NULL; } /* * Get the inode and fill in a single buffer. * BULKSTAT_FG_QUICK uses dip to fill it in. * BULKSTAT_FG_IGET uses igets. + * BULKSTAT_FG_INLINE uses dip if we have an + * inline attr fork, else igets. * See: xfs_bulkstat_one & xfs_dm_bulkstat_one. * This is also used to count inodes/blks, etc * in xfs_qm_quotacheck. diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h index be5f12e07d2..6926c373a0a 100644 --- a/fs/xfs/xfs_itable.h +++ b/fs/xfs/xfs_itable.h @@ -36,15 +36,16 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp, /* * Values for stat return value. */ -#define BULKSTAT_RV_NOTHING 0 -#define BULKSTAT_RV_DIDONE 1 -#define BULKSTAT_RV_GIVEUP 2 +#define BULKSTAT_RV_NOTHING 0 +#define BULKSTAT_RV_DIDONE 1 +#define BULKSTAT_RV_GIVEUP 2 /* * Values for bulkstat flag argument. */ -#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */ -#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ +#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */ +#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */ +#define BULKSTAT_FG_INLINE 0x4 /* No iget if inline attrs */ /* * Return stat information in bulk (by-inode) for the filesystem. -- cgit v1.2.3 From 51bdd70681e247184b81c2de61dbc26154511155 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:01:57 +1000 Subject: [XFS] When issuing metadata readahead, submit bio with READA not READ. SGI-PV: 944409 SGI-Modid: xfs-linux-melb:xfs-kern:26603a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_buf.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index f13503508c4..247adced6e1 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -1156,16 +1156,16 @@ _xfs_buf_ioapply( total_nr_pages = bp->b_page_count; map_i = 0; - if (bp->b_flags & _XBF_RUN_QUEUES) { - bp->b_flags &= ~_XBF_RUN_QUEUES; - rw = (bp->b_flags & XBF_READ) ? READ_SYNC : WRITE_SYNC; - } else { - rw = (bp->b_flags & XBF_READ) ? READ : WRITE; - } - if (bp->b_flags & XBF_ORDERED) { ASSERT(!(bp->b_flags & XBF_READ)); rw = WRITE_BARRIER; + } else if (bp->b_flags & _XBF_RUN_QUEUES) { + ASSERT(!(bp->b_flags & XBF_READ_AHEAD)); + bp->b_flags &= ~_XBF_RUN_QUEUES; + rw = (bp->b_flags & XBF_WRITE) ? WRITE_SYNC : READ_SYNC; + } else { + rw = (bp->b_flags & XBF_WRITE) ? WRITE : + (bp->b_flags & XBF_READ_AHEAD) ? READA : READ; } /* Special code path for reading a sub page size buffer in -- -- cgit v1.2.3 From 2627509330323efc88b5818065cba737e000de5c Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:02:03 +1000 Subject: [XFS] Drop unneeded endian conversion in bulkstat and start readahead for batches of inode cluster buffers at once, before any blocking reads are issued. SGI-PV: 944409 SGI-Modid: xfs-linux-melb:xfs-kern:26606a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_itable.c | 68 ++++++++++++++++++++++++----------------------------- 1 file changed, 31 insertions(+), 37 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 305a9d0436f..e6dbe6ba6fb 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -325,9 +325,9 @@ xfs_bulkstat( int i; /* loop index */ int icount; /* count of inodes good in irbuf */ xfs_ino_t ino; /* inode number (filesystem) */ - xfs_inobt_rec_t *irbp; /* current irec buffer pointer */ - xfs_inobt_rec_t *irbuf; /* start of irec buffer */ - xfs_inobt_rec_t *irbufend; /* end of good irec buffer entries */ + xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */ + xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ + xfs_inobt_rec_incore_t *irbufend; /* end of good irec buffer entries */ xfs_ino_t lastino=0; /* last inode number returned */ int nbcluster; /* # of blocks in a cluster */ int nicluster; /* # of inodes in a cluster */ @@ -398,7 +398,7 @@ xfs_bulkstat( * Allocate and initialize a btree cursor for ialloc btree. */ cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO, - (xfs_inode_t *)0, 0); + (xfs_inode_t *)0, 0); irbp = irbuf; irbufend = irbuf + nirbuf; end_of_ag = 0; @@ -435,9 +435,9 @@ xfs_bulkstat( gcnt++; } gfree |= XFS_INOBT_MASKN(0, chunkidx); - irbp->ir_startino = cpu_to_be32(gino); - irbp->ir_freecount = cpu_to_be32(gcnt); - irbp->ir_free = cpu_to_be64(gfree); + irbp->ir_startino = gino; + irbp->ir_freecount = gcnt; + irbp->ir_free = gfree; irbp++; agino = gino + XFS_INODES_PER_CHUNK; icount = XFS_INODES_PER_CHUNK - gcnt; @@ -491,11 +491,27 @@ xfs_bulkstat( } /* * If this chunk has any allocated inodes, save it. + * Also start read-ahead now for this chunk. */ if (gcnt < XFS_INODES_PER_CHUNK) { - irbp->ir_startino = cpu_to_be32(gino); - irbp->ir_freecount = cpu_to_be32(gcnt); - irbp->ir_free = cpu_to_be64(gfree); + /* + * Loop over all clusters in the next chunk. + * Do a readahead if there are any allocated + * inodes in that cluster. + */ + for (agbno = XFS_AGINO_TO_AGBNO(mp, gino), + chunkidx = 0; + chunkidx < XFS_INODES_PER_CHUNK; + chunkidx += nicluster, + agbno += nbcluster) { + if (XFS_INOBT_MASKN(chunkidx, + nicluster) & ~gfree) + xfs_btree_reada_bufs(mp, agno, + agbno, nbcluster); + } + irbp->ir_startino = gino; + irbp->ir_freecount = gcnt; + irbp->ir_free = gfree; irbp++; icount += XFS_INODES_PER_CHUNK - gcnt; } @@ -518,34 +534,12 @@ xfs_bulkstat( irbufend = irbp; for (irbp = irbuf; irbp < irbufend && ubleft >= statstruct_size; irbp++) { - /* - * Read-ahead the next chunk's worth of inodes. - */ - if (&irbp[1] < irbufend) { - /* - * Loop over all clusters in the next chunk. - * Do a readahead if there are any allocated - * inodes in that cluster. - */ - for (agbno = XFS_AGINO_TO_AGBNO(mp, - be32_to_cpu(irbp[1].ir_startino)), - chunkidx = 0; - chunkidx < XFS_INODES_PER_CHUNK; - chunkidx += nicluster, - agbno += nbcluster) { - if (XFS_INOBT_MASKN(chunkidx, - nicluster) & - ~(be64_to_cpu(irbp[1].ir_free))) - xfs_btree_reada_bufs(mp, agno, - agbno, nbcluster); - } - } /* * Now process this chunk of inodes. */ - for (agino = be32_to_cpu(irbp->ir_startino), chunkidx = 0, clustidx = 0; + for (agino = irbp->ir_startino, chunkidx = clustidx = 0; ubleft > 0 && - be32_to_cpu(irbp->ir_freecount) < XFS_INODES_PER_CHUNK; + irbp->ir_freecount < XFS_INODES_PER_CHUNK; chunkidx++, clustidx++, agino++) { ASSERT(chunkidx < XFS_INODES_PER_CHUNK); /* @@ -565,7 +559,7 @@ xfs_bulkstat( */ if ((chunkidx & (nicluster - 1)) == 0) { agbno = XFS_AGINO_TO_AGBNO(mp, - be32_to_cpu(irbp->ir_startino)) + + irbp->ir_startino) + ((chunkidx & nimask) >> mp->m_sb.sb_inopblog); @@ -605,13 +599,13 @@ xfs_bulkstat( /* * Skip if this inode is free. */ - if (XFS_INOBT_MASK(chunkidx) & be64_to_cpu(irbp->ir_free)) + if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) continue; /* * Count used inodes as free so we can tell * when the chunk is used up. */ - be32_add(&irbp->ir_freecount, 1); + irbp->ir_freecount++; ino = XFS_AGINO_TO_INO(mp, agno, agino); bno = XFS_AGB_TO_DADDR(mp, agno, agbno); if (!xfs_bulkstat_use_dinode(mp, flags, bp, -- cgit v1.2.3 From bb3c7d2936b6db6f5ded9abf4d215abe97af8372 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:02:09 +1000 Subject: [XFS] Increase the size of the buffer holding the local inode cluster list, to increase our potential readahead window and in turn improve bulkstat performance. SGI-PV: 944409 SGI-Modid: xfs-linux-melb:xfs-kern:26607a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_itable.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index e6dbe6ba6fb..315c9bcd3be 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -324,6 +324,8 @@ xfs_bulkstat( xfs_agino_t gino; /* current btree rec's start inode */ int i; /* loop index */ int icount; /* count of inodes good in irbuf */ + int irbsize; /* size of irec buffer in bytes */ + unsigned int kmflags; /* flags for allocating irec buffer */ xfs_ino_t ino; /* inode number (filesystem) */ xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */ xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ @@ -369,12 +371,20 @@ xfs_bulkstat( nimask = ~(nicluster - 1); nbcluster = nicluster >> mp->m_sb.sb_inopblog; /* - * Allocate a page-sized buffer for inode btree records. - * We could try allocating something smaller, but for normal - * calls we'll always (potentially) need the whole page. + * Allocate a local buffer for inode cluster btree records. + * This caps our maximum readahead window (so don't be stingy) + * but we must handle the case where we can't get a contiguous + * multi-page buffer, so we drop back toward pagesize; the end + * case we ensure succeeds, via appropriate allocation flags. */ - irbuf = kmem_alloc(NBPC, KM_SLEEP); - nirbuf = NBPC / sizeof(*irbuf); + irbsize = NBPP * 4; + kmflags = KM_SLEEP | KM_MAYFAIL; + while (!(irbuf = kmem_alloc(irbsize, kmflags))) { + if ((irbsize >>= 1) <= NBPP) + kmflags = KM_SLEEP; + } + nirbuf = irbsize / sizeof(*irbuf); + /* * Loop over the allocation groups, starting from the last * inode returned; 0 means start of the allocation group. @@ -672,7 +682,7 @@ xfs_bulkstat( /* * Done, we're either out of filesystem or space to put the data. */ - kmem_free(irbuf, NBPC); + kmem_free(irbuf, irbsize); *ubcountp = ubelem; if (agno >= mp->m_sb.sb_agcount) { /* -- cgit v1.2.3 From a3c6685eaa1b6c5cf05b084b3bc91895e253ad2c Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:02:14 +1000 Subject: [XFS] Ensure xlog_state_do_callback does not report spurious warnings on ramdisks. SGI-PV: 954802 SGI-Modid: xfs-linux-melb:xfs-kern:26627a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_log.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 21ac1a67e3e..2a46919110f 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2212,9 +2212,13 @@ xlog_state_do_callback( iclog = iclog->ic_next; } while (first_iclog != iclog); - if (repeats && (repeats % 10) == 0) { + + if (repeats > 5000) { + flushcnt += repeats; + repeats = 0; xfs_fs_cmn_err(CE_WARN, log->l_mp, - "xlog_state_do_callback: looping %d", repeats); + "%s: possible infinite loop (%d iterations)", + __FUNCTION__, flushcnt); } } while (!ioerrors && loopdidcallbacks); @@ -2246,6 +2250,7 @@ xlog_state_do_callback( } #endif + flushcnt = 0; if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) { flushcnt = log->l_flushcnt; log->l_flushcnt = 0; -- cgit v1.2.3 From 745b1f47fc0c68dbb1ff440eec8889f61e57194b Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:02:23 +1000 Subject: [XFS] Remove last bulkstat false-positives with debug kernels. SGI-PV: 953819 SGI-Modid: xfs-linux-melb:xfs-kern:26628a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_ialloc.c | 1 + fs/xfs/xfs_iget.c | 17 ++++++++--------- fs/xfs/xfs_inode.c | 7 ++++--- fs/xfs/xfs_inode.h | 11 +++++++---- fs/xfs/xfs_itable.c | 3 ++- 5 files changed, 22 insertions(+), 17 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 76813d608de..a446e5a115c 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c @@ -1195,6 +1195,7 @@ xfs_dilocate( "(0x%llx)", ino, XFS_AGINO_TO_INO(mp, agno, agino)); } + xfs_stack_trace(); #endif /* DEBUG */ return XFS_ERROR(EINVAL); } diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 0724df7fabb..109000a4bc8 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -290,11 +290,11 @@ again: finish_inode: if (ip->i_d.di_mode == 0) { - if (!(flags & IGET_CREATE)) + if (!(flags & XFS_IGET_CREATE)) return ENOENT; xfs_iocore_inode_reinit(ip); } - + if (lock_flags != 0) xfs_ilock(ip, lock_flags); @@ -320,21 +320,20 @@ finish_inode: * Read the disk inode attributes into a new inode structure and get * a new vnode for it. This should also initialize i_ino and i_mount. */ - error = xfs_iread(mp, tp, ino, &ip, bno); - if (error) { + error = xfs_iread(mp, tp, ino, &ip, bno, + (flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0); + if (error) return error; - } vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address); xfs_inode_lock_init(ip, vp); xfs_iocore_inode_init(ip); - if (lock_flags != 0) { + if (lock_flags) xfs_ilock(ip, lock_flags); - } - - if ((ip->i_d.di_mode == 0) && !(flags & IGET_CREATE)) { + + if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { xfs_idestroy(ip); return ENOENT; } diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 1f8ecff8553..66a78287a95 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -854,7 +854,8 @@ xfs_iread( xfs_trans_t *tp, xfs_ino_t ino, xfs_inode_t **ipp, - xfs_daddr_t bno) + xfs_daddr_t bno, + uint imap_flags) { xfs_buf_t *bp; xfs_dinode_t *dip; @@ -874,7 +875,7 @@ xfs_iread( * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will * know that this is a new incore inode. */ - error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, 0); + error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags); if (error) { kmem_zone_free(xfs_inode_zone, ip); return error; @@ -1113,7 +1114,7 @@ xfs_ialloc( * to prevent others from looking at until we're done. */ error = xfs_trans_iget(tp->t_mountp, tp, ino, - IGET_CREATE, XFS_ILOCK_EXCL, &ip); + XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip); if (error != 0) { return error; } diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index d10b76ed1e5..fdb89f72db9 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -389,11 +389,14 @@ typedef struct xfs_inode { (((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID)) /* - * xfs_iget.c prototypes. + * Flags for xfs_iget() */ +#define XFS_IGET_CREATE 0x1 +#define XFS_IGET_BULKSTAT 0x2 -#define IGET_CREATE 1 - +/* + * xfs_iget.c prototypes. + */ void xfs_ihash_init(struct xfs_mount *); void xfs_ihash_free(struct xfs_mount *); void xfs_chash_init(struct xfs_mount *); @@ -425,7 +428,7 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *, xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **, xfs_daddr_t, uint); int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, - xfs_inode_t **, xfs_daddr_t); + xfs_inode_t **, xfs_daddr_t, uint); int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 315c9bcd3be..61268994065 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -52,7 +52,8 @@ xfs_bulkstat_one_iget( bhv_vnode_t *vp; int error; - error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno); + error = xfs_iget(mp, NULL, ino, + XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno); if (error) { *stat = BULKSTAT_RV_NOTHING; return error; -- cgit v1.2.3 From 17370097dace78c93d6fa32110983e74b981d192 Mon Sep 17 00:00:00 2001 From: Vlad Apostolov Date: Thu, 28 Sep 2006 11:02:30 +1000 Subject: [XFS] pass file mode on DMAPI remove events SGI-PV: 953687 SGI-Modid: xfs-linux-melb:xfs-kern:26639a Signed-off-by: Vlad Apostolov Signed-off-by: Tim Shimmin --- fs/xfs/xfs_vnodeops.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 4fbc3e1cac0..1a6782eaf5d 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -2366,10 +2366,15 @@ xfs_remove( namelen = VNAMELEN(dentry); + if (!xfs_get_dir_entry(dentry, &ip)) { + dm_di_mode = ip->i_d.di_mode; + IRELE(ip); + } + if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, - name, NULL, 0, 0, 0); + name, NULL, dm_di_mode, 0, 0); if (error) return error; } @@ -2995,7 +3000,7 @@ xfs_rmdir( int cancel_flags; int committed; bhv_vnode_t *dir_vp; - int dm_di_mode = 0; + int dm_di_mode = S_IFDIR; int last_cdp_link; int namelen; uint resblks; @@ -3010,11 +3015,16 @@ xfs_rmdir( return XFS_ERROR(EIO); namelen = VNAMELEN(dentry); + if (!xfs_get_dir_entry(dentry, &cdp)) { + dm_di_mode = cdp->i_d.di_mode; + IRELE(cdp); + } + if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) { error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp, DM_RIGHT_NULL, NULL, DM_RIGHT_NULL, - name, NULL, 0, 0, 0); + name, NULL, dm_di_mode, 0, 0); if (error) return XFS_ERROR(error); } -- cgit v1.2.3 From 43129c16e85119355d352e10ff4b30a08053228c Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 28 Sep 2006 11:02:37 +1000 Subject: [XFS] Remove a couple of unused BUF macros SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26746a Signed-off-by: Eric Sandeen Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_buf.h | 5 ----- fs/xfs/xfs_buf_item.c | 2 -- 2 files changed, 7 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 7858703ed84..2afc6d4a9ee 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h @@ -298,11 +298,6 @@ extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *); #define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) #define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) -#define XFS_BUF_ISUNINITIAL(bp) (0) -#define XFS_BUF_UNUNINITIAL(bp) (0) - -#define XFS_BUF_BP_ISMAPPED(bp) (1) - #define XFS_BUF_IODONE_FUNC(bp) ((bp)->b_iodone) #define XFS_BUF_SET_IODONE_FUNC(bp, func) ((bp)->b_iodone = (func)) #define XFS_BUF_CLR_IODONE_FUNC(bp) ((bp)->b_iodone = NULL) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index a4aa53974f7..4597381b8ff 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -234,7 +234,6 @@ xfs_buf_item_format( ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || (bip->bli_flags & XFS_BLI_STALE)); bp = bip->bli_buf; - ASSERT(XFS_BUF_BP_ISMAPPED(bp)); vecp = log_vector; /* @@ -901,7 +900,6 @@ xfs_buf_item_relse( XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list); if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) && (XFS_BUF_IODONE_FUNC(bp) != NULL)) { - ASSERT((XFS_BUF_ISUNINITIAL(bp)) == 0); XFS_BUF_CLR_IODONE_FUNC(bp); } -- cgit v1.2.3 From 065d312e15902976d256ddaf396a7950ec0350a8 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 28 Sep 2006 11:02:44 +1000 Subject: [XFS] Remove unused iop_abort log item operation SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26747a Signed-off-by: Eric Sandeen Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/quota/xfs_dquot_item.c | 26 ---------------- fs/xfs/xfs_buf_item.c | 20 ------------- fs/xfs/xfs_extfree_item.c | 69 ++----------------------------------------- fs/xfs/xfs_inode_item.c | 16 ---------- fs/xfs/xfs_trans.h | 2 -- 5 files changed, 2 insertions(+), 131 deletions(-) (limited to 'fs') diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index 5b2dcc58b24..33ad5af386e 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c @@ -381,18 +381,6 @@ xfs_qm_dquot_logitem_unlock( } -/* - * The transaction with the dquot locked has aborted. The dquot - * must not be dirty within the transaction. We simply unlock just - * as if the transaction had been cancelled. - */ -STATIC void -xfs_qm_dquot_logitem_abort( - xfs_dq_logitem_t *ql) -{ - xfs_qm_dquot_logitem_unlock(ql); -} - /* * this needs to stamp an lsn into the dquot, I think. * rpc's that look at user dquot's would then have to @@ -426,7 +414,6 @@ STATIC struct xfs_item_ops xfs_dquot_item_ops = { .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_qm_dquot_logitem_committed, .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push, - .iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_abort, .iop_pushbuf = (void(*)(xfs_log_item_t*)) xfs_qm_dquot_logitem_pushbuf, .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) @@ -558,17 +545,6 @@ xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn) return (lsn); } -/* - * The transaction of which this QUOTAOFF is a part has been aborted. - * Just clean up after ourselves. - * Shouldn't this never happen in the case of qoffend logitems? XXX - */ -STATIC void -xfs_qm_qoff_logitem_abort(xfs_qoff_logitem_t *qf) -{ - kmem_free(qf, sizeof(xfs_qoff_logitem_t)); -} - /* * There isn't much you can do to push on an quotaoff item. It is simply * stuck waiting for the log to be flushed to disk. @@ -644,7 +620,6 @@ STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_qm_qoffend_logitem_committed, .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push, - .iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort, .iop_pushbuf = NULL, .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_qm_qoffend_logitem_committing @@ -667,7 +642,6 @@ STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = { .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_qm_qoff_logitem_committed, .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push, - .iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort, .iop_pushbuf = NULL, .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_qm_qoff_logitem_committing diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 4597381b8ff..7a55c248ea7 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -626,25 +626,6 @@ xfs_buf_item_committed( return (lsn); } -/* - * This is called when the transaction holding the buffer is aborted. - * Just behave as if the transaction had been cancelled. If we're shutting down - * and have aborted this transaction, we'll trap this buffer when it tries to - * get written out. - */ -STATIC void -xfs_buf_item_abort( - xfs_buf_log_item_t *bip) -{ - xfs_buf_t *bp; - - bp = bip->bli_buf; - xfs_buftrace("XFS_ABORT", bp); - XFS_BUF_SUPER_STALE(bp); - xfs_buf_item_unlock(bip); - return; -} - /* * This is called to asynchronously write the buffer associated with this * buf log item out to disk. The buffer will already have been locked by @@ -692,7 +673,6 @@ STATIC struct xfs_item_ops xfs_buf_item_ops = { .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_buf_item_committed, .iop_push = (void(*)(xfs_log_item_t*))xfs_buf_item_push, - .iop_abort = (void(*)(xfs_log_item_t*))xfs_buf_item_abort, .iop_pushbuf = NULL, .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_buf_item_committing diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 6cf6d8769b9..6dba78199fa 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -33,9 +33,6 @@ kmem_zone_t *xfs_efi_zone; kmem_zone_t *xfs_efd_zone; STATIC void xfs_efi_item_unlock(xfs_efi_log_item_t *); -STATIC void xfs_efi_item_abort(xfs_efi_log_item_t *); -STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *); - void xfs_efi_item_free(xfs_efi_log_item_t *efip) @@ -184,7 +181,7 @@ STATIC void xfs_efi_item_unlock(xfs_efi_log_item_t *efip) { if (efip->efi_item.li_flags & XFS_LI_ABORTED) - xfs_efi_item_abort(efip); + xfs_efi_item_free(efip); return; } @@ -201,18 +198,6 @@ xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn) return lsn; } -/* - * This is called when the transaction logging the EFI is aborted. - * Free up the EFI and return. No need to clean up the slot for - * the item in the transaction. That was done by the unpin code - * which is called prior to this routine in the abort/fs-shutdown path. - */ -STATIC void -xfs_efi_item_abort(xfs_efi_log_item_t *efip) -{ - xfs_efi_item_free(efip); -} - /* * There isn't much you can do to push on an efi item. It is simply * stuck waiting for all of its corresponding efd items to be @@ -255,7 +240,6 @@ STATIC struct xfs_item_ops xfs_efi_item_ops = { .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_efi_item_committed, .iop_push = (void(*)(xfs_log_item_t*))xfs_efi_item_push, - .iop_abort = (void(*)(xfs_log_item_t*))xfs_efi_item_abort, .iop_pushbuf = NULL, .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_efi_item_committing @@ -386,33 +370,6 @@ xfs_efi_release(xfs_efi_log_item_t *efip, } } -/* - * This is called when the transaction that should be committing the - * EFD corresponding to the given EFI is aborted. The committed and - * canceled flags are used to coordinate the freeing of the EFI and - * the references by the transaction that committed it. - */ -STATIC void -xfs_efi_cancel( - xfs_efi_log_item_t *efip) -{ - xfs_mount_t *mp; - SPLDECL(s); - - mp = efip->efi_item.li_mountp; - AIL_LOCK(mp, s); - if (efip->efi_flags & XFS_EFI_COMMITTED) { - /* - * xfs_trans_delete_ail() drops the AIL lock. - */ - xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s); - xfs_efi_item_free(efip); - } else { - efip->efi_flags |= XFS_EFI_CANCELED; - AIL_UNLOCK(mp, s); - } -} - STATIC void xfs_efd_item_free(xfs_efd_log_item_t *efdp) { @@ -514,7 +471,7 @@ STATIC void xfs_efd_item_unlock(xfs_efd_log_item_t *efdp) { if (efdp->efd_item.li_flags & XFS_LI_ABORTED) - xfs_efd_item_abort(efdp); + xfs_efd_item_free(efdp); return; } @@ -540,27 +497,6 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn) return (xfs_lsn_t)-1; } -/* - * The transaction of which this EFD is a part has been aborted. - * Inform its companion EFI of this fact and then clean up after - * ourselves. No need to clean up the slot for the item in the - * transaction. That was done by the unpin code which is called - * prior to this routine in the abort/fs-shutdown path. - */ -STATIC void -xfs_efd_item_abort(xfs_efd_log_item_t *efdp) -{ - /* - * If we got a log I/O error, it's always the case that the LR with the - * EFI got unpinned and freed before the EFD got aborted. So don't - * reference the EFI at all in that case. - */ - if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0) - xfs_efi_cancel(efdp->efd_efip); - - xfs_efd_item_free(efdp); -} - /* * There isn't much you can do to push on an efd item. It is simply * stuck waiting for the log to be flushed to disk. @@ -602,7 +538,6 @@ STATIC struct xfs_item_ops xfs_efd_item_ops = { .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_efd_item_committed, .iop_push = (void(*)(xfs_log_item_t*))xfs_efd_item_push, - .iop_abort = (void(*)(xfs_log_item_t*))xfs_efd_item_abort, .iop_pushbuf = NULL, .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_efd_item_committing diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index f8e80d8e723..a7a92251eb5 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -742,21 +742,6 @@ xfs_inode_item_committed( return (lsn); } -/* - * The transaction with the inode locked has aborted. The inode - * must not be dirty within the transaction (unless we're forcibly - * shutting down). We simply unlock just as if the transaction - * had been cancelled. - */ -STATIC void -xfs_inode_item_abort( - xfs_inode_log_item_t *iip) -{ - xfs_inode_item_unlock(iip); - return; -} - - /* * This gets called by xfs_trans_push_ail(), when IOP_TRYLOCK * failed to get the inode flush lock but did get the inode locked SHARED. @@ -915,7 +900,6 @@ STATIC struct xfs_item_ops xfs_inode_item_ops = { .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_inode_item_committed, .iop_push = (void(*)(xfs_log_item_t*))xfs_inode_item_push, - .iop_abort = (void(*)(xfs_log_item_t*))xfs_inode_item_abort, .iop_pushbuf = (void(*)(xfs_log_item_t*))xfs_inode_item_pushbuf, .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t)) xfs_inode_item_committing diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 9dc88b38060..c68e00105d2 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -149,7 +149,6 @@ typedef struct xfs_item_ops { void (*iop_unlock)(xfs_log_item_t *); xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t); void (*iop_push)(xfs_log_item_t *); - void (*iop_abort)(xfs_log_item_t *); void (*iop_pushbuf)(xfs_log_item_t *); void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); } xfs_item_ops_t; @@ -163,7 +162,6 @@ typedef struct xfs_item_ops { #define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip) #define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn) #define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip) -#define IOP_ABORT(ip) (*(ip)->li_ops->iop_abort)(ip) #define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip) #define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn) -- cgit v1.2.3 From 3f89243c5b987dd55f8eec6fd54be05887d69bc6 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 28 Sep 2006 11:02:57 +1000 Subject: [XFS] Remove several macros that are no longer used anywhere SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26749a Signed-off-by: Eric Sandeen Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_buf.h | 2 -- fs/xfs/linux-2.6/xfs_linux.h | 7 ------- fs/xfs/quota/xfs_qm.h | 6 ------ fs/xfs/quota/xfs_quota_priv.h | 2 -- fs/xfs/xfs_error.h | 8 -------- fs/xfs/xfs_fs.h | 8 +------- fs/xfs/xfs_log.h | 8 -------- fs/xfs/xfs_log_priv.h | 4 ---- fs/xfs/xfs_quota.h | 2 -- fs/xfs/xfs_sb.h | 22 ---------------------- 10 files changed, 1 insertion(+), 68 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 2afc6d4a9ee..9dd235cb010 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h @@ -388,8 +388,6 @@ static inline int XFS_bwrite(xfs_buf_t *bp) return error; } -#define XFS_bdwrite(bp) xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC) - static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp) { bp->b_strat = xfs_bdstrat_cb; diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index a13f75c1a93..14d840208e8 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h @@ -148,11 +148,7 @@ BUFFER_FNS(PrivateStart, unwritten); (current->flags = ((current->flags & ~(f)) | (*(sp) & (f)))) #define NBPP PAGE_SIZE -#define DPPSHFT (PAGE_SHIFT - 9) #define NDPP (1 << (PAGE_SHIFT - 9)) -#define dtop(DD) (((DD) + NDPP - 1) >> DPPSHFT) -#define dtopt(DD) ((DD) >> DPPSHFT) -#define dpoff(DD) ((DD) & (NDPP-1)) #define NBBY 8 /* number of bits per byte */ #define NBPC PAGE_SIZE /* Number of bytes per click */ @@ -172,8 +168,6 @@ BUFFER_FNS(PrivateStart, unwritten); #define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT) #define btoc64(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) #define btoct64(x) ((__uint64_t)(x)>>BPCSHIFT) -#define io_btoc(x) (((__psunsigned_t)(x)+(IO_NBPC-1))>>IO_BPCSHIFT) -#define io_btoct(x) ((__psunsigned_t)(x)>>IO_BPCSHIFT) /* off_t bytes to clicks */ #define offtoc(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT) @@ -186,7 +180,6 @@ BUFFER_FNS(PrivateStart, unwritten); #define ctob(x) ((__psunsigned_t)(x)<>BPCSHIFT) #define ctob64(x) ((__uint64_t)(x)<>BPCSHIFT) diff --git a/fs/xfs/quota/xfs_qm.h b/fs/xfs/quota/xfs_qm.h index 4568deb6da8..689407de0a2 100644 --- a/fs/xfs/quota/xfs_qm.h +++ b/fs/xfs/quota/xfs_qm.h @@ -55,12 +55,6 @@ extern kmem_zone_t *qm_dqtrxzone; #define XFS_QM_HASHSIZE_LOW (NBPP / sizeof(xfs_dqhash_t)) #define XFS_QM_HASHSIZE_HIGH ((NBPP * 4) / sizeof(xfs_dqhash_t)) -/* - * We output a cmn_err when quotachecking a quota file with more than - * this many fsbs. - */ -#define XFS_QM_BIG_QCHECK_NBLKS 500 - /* * This defines the unit of allocation of dquots. * Currently, it is just one file system block, and a 4K blk contains 30 diff --git a/fs/xfs/quota/xfs_quota_priv.h b/fs/xfs/quota/xfs_quota_priv.h index b7ddd04aae3..a8b85e2be9d 100644 --- a/fs/xfs/quota/xfs_quota_priv.h +++ b/fs/xfs/quota/xfs_quota_priv.h @@ -75,7 +75,6 @@ static inline int XQMISLCKD(struct xfs_dqhash *h) #define xfs_qm_freelist_lock(qm) XQMLCK(&((qm)->qm_dqfreelist)) #define xfs_qm_freelist_unlock(qm) XQMUNLCK(&((qm)->qm_dqfreelist)) -#define XFS_QM_IS_FREELIST_LOCKED(qm) XQMISLCKD(&((qm)->qm_dqfreelist)) /* * Hash into a bucket in the dquot hash table, based on . @@ -170,6 +169,5 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \ #define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \ (((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \ (((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???"))) -#define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY") #endif /* __XFS_QUOTA_PRIV_H__ */ diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index bc43163456e..f90fd500b94 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h @@ -18,14 +18,6 @@ #ifndef __XFS_ERROR_H__ #define __XFS_ERROR_H__ -#define XFS_ERECOVER 1 /* Failure to recover log */ -#define XFS_ELOGSTAT 2 /* Failure to stat log in user space */ -#define XFS_ENOLOGSPACE 3 /* Reservation too large */ -#define XFS_ENOTSUP 4 /* Operation not supported */ -#define XFS_ENOLSN 5 /* Can't find the lsn you asked for */ -#define XFS_ENOTFOUND 6 -#define XFS_ENOTXFS 7 /* Not XFS filesystem */ - #ifdef DEBUG #define XFS_ERROR_NTRAP 10 extern int xfs_etrap[XFS_ERROR_NTRAP]; diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 0f0ad153595..1335449841c 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h @@ -22,8 +22,6 @@ * SGI's XFS filesystem's major stuff (constants, structures) */ -#define XFS_NAME "xfs" - /* * Direct I/O attribute record used with XFS_IOC_DIOINFO * d_miniosz is the min xfer size, xfer size multiple and file seek offset @@ -426,11 +424,7 @@ typedef struct xfs_handle { - (char *) &(handle)) \ + (handle).ha_fid.xfs_fid_len) -#define XFS_HANDLE_CMP(h1, h2) memcmp(h1, h2, sizeof(xfs_handle_t)) - -#define FSHSIZE sizeof(fsid_t) - -/* +/* * Flags for going down operation */ #define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */ diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index eacb3d4987f..ebbe93f4f97 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h @@ -47,17 +47,11 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) * Macros, structures, prototypes for interface to the log manager. */ -/* - * Flags to xfs_log_mount - */ -#define XFS_LOG_RECOVER 0x1 - /* * Flags to xfs_log_done() */ #define XFS_LOG_REL_PERM_RESERV 0x1 - /* * Flags to xfs_log_reserve() * @@ -70,8 +64,6 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) #define XFS_LOG_SLEEP 0x0 #define XFS_LOG_NOSLEEP 0x1 #define XFS_LOG_PERM_RESERV 0x2 -#define XFS_LOG_RESV_ALL (XFS_LOG_NOSLEEP|XFS_LOG_PERM_RESERV) - /* * Flags to xfs_log_force() diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 34bcbf50789..7bf5046d8d2 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -32,7 +32,6 @@ struct xfs_mount; #define XLOG_MIN_ICLOGS 2 #define XLOG_MED_ICLOGS 4 #define XLOG_MAX_ICLOGS 8 -#define XLOG_CALLBACK_SIZE 10 #define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */ #define XLOG_VERSION_1 1 #define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */ @@ -149,9 +148,6 @@ struct xfs_mount; #define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */ #define XLOG_END_TRANS 0x10 /* End a continued transaction */ #define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */ -#define XLOG_SKIP_TRANS (XLOG_COMMIT_TRANS | XLOG_CONTINUE_TRANS | \ - XLOG_WAS_CONT_TRANS | XLOG_END_TRANS | \ - XLOG_UNMOUNT_TRANS) #ifdef __KERNEL__ /* diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index acb853b33eb..9dcb32aa4e2 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -281,8 +281,6 @@ typedef struct xfs_qoff_logformat { XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\ XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\ XFS_GQUOTA_ACCT) -#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \ - XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE) /* diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h index bf168a91ddb..467854b45c8 100644 --- a/fs/xfs/xfs_sb.h +++ b/fs/xfs/xfs_sb.h @@ -60,10 +60,6 @@ struct xfs_mount; XFS_SB_VERSION_LOGV2BIT | \ XFS_SB_VERSION_SECTORBIT | \ XFS_SB_VERSION_MOREBITSBIT) -#define XFS_SB_VERSION_OKSASHBITS \ - (XFS_SB_VERSION_NUMBITS | \ - XFS_SB_VERSION_REALFBITS | \ - XFS_SB_VERSION_OKSASHFBITS) #define XFS_SB_VERSION_OKREALBITS \ (XFS_SB_VERSION_NUMBITS | \ XFS_SB_VERSION_OKREALFBITS | \ @@ -81,9 +77,6 @@ struct xfs_mount; #define XFS_SB_VERSION2_RESERVED2BIT 0x00000002 #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ -#define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that - require changing - PROM and SASH */ #define XFS_SB_VERSION2_OKREALFBITS \ (XFS_SB_VERSION2_ATTR2BIT) @@ -238,12 +231,6 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp) } #endif /* __KERNEL__ */ -#define XFS_SB_GOOD_SASH_VERSION(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_OKSASHBITS))) - #define XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v) static inline unsigned xfs_sb_version_tonew(unsigned v) { @@ -461,15 +448,6 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp) * File system sector to basic block conversions. */ #define XFS_FSS_TO_BB(mp,sec) ((sec) << (mp)->m_sectbb_log) -#define XFS_BB_TO_FSS(mp,bb) \ - (((bb) + (XFS_FSS_TO_BB(mp,1) - 1)) >> (mp)->m_sectbb_log) -#define XFS_BB_TO_FSST(mp,bb) ((bb) >> (mp)->m_sectbb_log) - -/* - * File system sector to byte conversions. - */ -#define XFS_FSS_TO_B(mp,sectno) ((xfs_fsize_t)(sectno) << (mp)->m_sb.sb_sectlog) -#define XFS_B_TO_FSST(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_sectlog) /* * File system block to basic block conversions. -- cgit v1.2.3 From efb8ad7e9431a430a75d44288614cf6047ff4baa Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:03:05 +1000 Subject: [XFS] Add a debug flag for allocations which are known to be larger than one page. SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26800a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/kmem.c | 8 ++++++++ fs/xfs/linux-2.6/kmem.h | 3 ++- fs/xfs/linux-2.6/xfs_buf.c | 2 +- fs/xfs/quota/xfs_qm.c | 6 +++--- fs/xfs/support/ktrace.c | 2 +- fs/xfs/xfs_iget.c | 4 ++-- fs/xfs/xfs_log.c | 2 +- 7 files changed, 18 insertions(+), 9 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c index aba7fcf881a..f77fe5c8fcc 100644 --- a/fs/xfs/linux-2.6/kmem.c +++ b/fs/xfs/linux-2.6/kmem.c @@ -34,6 +34,14 @@ kmem_alloc(size_t size, unsigned int __nocast flags) gfp_t lflags = kmem_flags_convert(flags); void *ptr; +#ifdef DEBUG + if (unlikely(!(flags & KM_LARGE) && (size > PAGE_SIZE))) { + printk(KERN_WARNING "Large %s attempt, size=%ld\n", + __FUNCTION__, (long)size); + dump_stack(); + } +#endif + do { if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS) ptr = kmalloc(size, lflags); diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h index 0e8293c5a32..6d24274fb3c 100644 --- a/fs/xfs/linux-2.6/kmem.h +++ b/fs/xfs/linux-2.6/kmem.h @@ -30,6 +30,7 @@ #define KM_NOSLEEP 0x0002u #define KM_NOFS 0x0004u #define KM_MAYFAIL 0x0008u +#define KM_LARGE 0x0010u /* * We use a special process flag to avoid recursive callbacks into @@ -41,7 +42,7 @@ kmem_flags_convert(unsigned int __nocast flags) { gfp_t lflags; - BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL)); + BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL|KM_LARGE)); if (flags & KM_NOSLEEP) { lflags = GFP_ATOMIC | __GFP_NOWARN; diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 247adced6e1..58b6599de61 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -768,7 +768,7 @@ xfs_buf_get_noaddr( _xfs_buf_initialize(bp, target, 0, len, 0); try_again: - data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL); + data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE); if (unlikely(data == NULL)) goto fail_free_buf; diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index e23e45535c4..3f86c7c0464 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -112,17 +112,17 @@ xfs_Gqm_init(void) { xfs_dqhash_t *udqhash, *gdqhash; xfs_qm_t *xqm; - uint i, hsize, flags = KM_SLEEP | KM_MAYFAIL; + uint i, hsize, flags = KM_SLEEP | KM_MAYFAIL | KM_LARGE; /* * Initialize the dquot hash tables. */ hsize = XFS_QM_HASHSIZE_HIGH; - while (!(udqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), flags))) { + while (!(udqhash = kmem_zalloc(hsize * sizeof(*udqhash), flags))) { if ((hsize >>= 1) <= XFS_QM_HASHSIZE_LOW) flags = KM_SLEEP; } - gdqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), KM_SLEEP); + gdqhash = kmem_zalloc(hsize * sizeof(*gdqhash), KM_SLEEP | KM_LARGE); ndquot = hsize << 8; xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP); diff --git a/fs/xfs/support/ktrace.c b/fs/xfs/support/ktrace.c index addf5a7ea06..5cf2e86caa7 100644 --- a/fs/xfs/support/ktrace.c +++ b/fs/xfs/support/ktrace.c @@ -75,7 +75,7 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep) sleep); } else { ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)), - sleep); + sleep | KM_LARGE); } if (ktep == NULL) { diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 109000a4bc8..30eebc2fd90 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -50,7 +50,7 @@ void xfs_ihash_init(xfs_mount_t *mp) { __uint64_t icount; - uint i, flags = KM_SLEEP | KM_MAYFAIL; + uint i, flags = KM_SLEEP | KM_MAYFAIL | KM_LARGE; if (!mp->m_ihsize) { icount = mp->m_maxicount ? mp->m_maxicount : @@ -95,7 +95,7 @@ xfs_chash_init(xfs_mount_t *mp) mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize); mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize * sizeof(xfs_chash_t), - KM_SLEEP); + KM_SLEEP | KM_LARGE); for (i = 0; i < mp->m_chsize; i++) { spinlock_init(&mp->m_chash[i].ch_lock,"xfshash"); } diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 2a46919110f..ac999789a44 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1196,7 +1196,7 @@ xlog_alloc_log(xfs_mount_t *mp, kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP); iclog = *iclogp; iclog->hic_data = (xlog_in_core_2_t *) - kmem_zalloc(iclogsize, KM_SLEEP); + kmem_zalloc(iclogsize, KM_SLEEP | KM_LARGE); iclog->ic_prev = prev_iclog; prev_iclog = iclog; -- cgit v1.2.3 From 948ecdb4c118293d2f3e267eec642c30c5d3a056 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:03:13 +1000 Subject: [XFS] Be more defensive with page flags (error/private) for metadata buffers. SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26801a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_buf.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 58b6599de61..9bbadafdcb0 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -318,8 +318,12 @@ xfs_buf_free( if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) free_address(bp->b_addr - bp->b_offset); - for (i = 0; i < bp->b_page_count; i++) - page_cache_release(bp->b_pages[i]); + for (i = 0; i < bp->b_page_count; i++) { + struct page *page = bp->b_pages[i]; + + ASSERT(!PagePrivate(page)); + page_cache_release(page); + } _xfs_buf_free_pages(bp); } else if (bp->b_flags & _XBF_KMEM_ALLOC) { /* @@ -400,6 +404,7 @@ _xfs_buf_lookup_pages( nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset); size -= nbytes; + ASSERT(!PagePrivate(page)); if (!PageUptodate(page)) { page_count--; if (blocksize >= PAGE_CACHE_SIZE) { @@ -1117,10 +1122,10 @@ xfs_buf_bio_end_io( do { struct page *page = bvec->bv_page; + ASSERT(!PagePrivate(page)); if (unlikely(bp->b_error)) { if (bp->b_flags & XBF_READ) ClearPageUptodate(page); - SetPageError(page); } else if (blocksize >= PAGE_CACHE_SIZE) { SetPageUptodate(page); } else if (!PagePrivate(page) && -- cgit v1.2.3 From 572d95f49f3652fffe8242c4498b85f4083e52ab Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:03:20 +1000 Subject: [XFS] Improve error handling for the zero-fsblock extent detection code. SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26802a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_globals.c | 2 +- fs/xfs/xfs_bmap.c | 27 +++++++------ fs/xfs/xfs_error.h | 1 + fs/xfs/xfs_iomap.c | 89 ++++++++++++++++-------------------------- 4 files changed, 51 insertions(+), 68 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c index 6c162c3dde7..ed3a5e1b4b6 100644 --- a/fs/xfs/linux-2.6/xfs_globals.c +++ b/fs/xfs/linux-2.6/xfs_globals.c @@ -34,7 +34,7 @@ xfs_param_t xfs_params = { .restrict_chown = { 0, 1, 1 }, .sgid_inherit = { 0, 0, 1 }, .symlink_mode = { 0, 0, 1 }, - .panic_mask = { 0, 0, 127 }, + .panic_mask = { 0, 0, 255 }, .error_level = { 0, 3, 11 }, .syncd_timer = { 1*100, 30*100, 7200*100}, .stats_clear = { 0, 0, 1 }, diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index e28146fe046..5b050c06795 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */ xfs_bmap_search_extents( xfs_inode_t *ip, /* incore inode pointer */ xfs_fileoff_t bno, /* block number searched for */ - int whichfork, /* data or attr fork */ + int fork, /* data or attr fork */ int *eofp, /* out: end of file found */ xfs_extnum_t *lastxp, /* out: last extent index */ xfs_bmbt_irec_t *gotp, /* out: extent entry found */ @@ -3713,25 +3713,28 @@ xfs_bmap_search_extents( { xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_rec_t *ep; /* extent record pointer */ - int rt; /* realtime flag */ XFS_STATS_INC(xs_look_exlist); - ifp = XFS_IFORK_PTR(ip, whichfork); + ifp = XFS_IFORK_PTR(ip, fork); ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); - rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); - if (unlikely(!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, + if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) && + !(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) { + xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, + "Access to block zero in inode %llu " + "start_block: %llx start_off: %llx " + "blkcnt: %llx extent-state: %x lastx: %x\n", + (unsigned long long)ip->i_ino, (unsigned long long)gotp->br_startblock, (unsigned long long)gotp->br_startoff, (unsigned long long)gotp->br_blockcount, - gotp->br_state); - } - return ep; + gotp->br_state, *lastxp); + *lastxp = NULLEXTNUM; + *eofp = 1; + return NULL; + } + return ep; } diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h index f90fd500b94..0893e16b7d8 100644 --- a/fs/xfs/xfs_error.h +++ b/fs/xfs/xfs_error.h @@ -167,6 +167,7 @@ extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud); #define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010 #define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020 #define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040 +#define XFS_PTAG_FSBLOCK_ZERO 0x00000080 struct xfs_mount; /* PRINTFLIKE4 */ diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index f1949c16df1..19655124da7 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -398,6 +398,23 @@ xfs_flush_space( return 1; } +STATIC int +xfs_cmn_err_fsblock_zero( + xfs_inode_t *ip, + xfs_bmbt_irec_t *imap) +{ + xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount, + "Access to block zero in inode %llu " + "start_block: %llx start_off: %llx " + "blkcnt: %llx extent-state: %x\n", + (unsigned long long)ip->i_ino, + (unsigned long long)imap->br_startblock, + (unsigned long long)imap->br_startoff, + (unsigned long long)imap->br_blockcount, + imap->br_state); + return EFSCORRUPTED; +} + int xfs_iomap_write_direct( xfs_inode_t *ip, @@ -536,23 +553,17 @@ xfs_iomap_write_direct( * Copy any maps to caller's array and return any error. */ if (nimaps == 0) { - error = (ENOSPC); + error = ENOSPC; + goto error_out; + } + + if (unlikely(!imap.br_startblock && !(io->io_flags & XFS_IOCORE_RT))) { + error = xfs_cmn_err_fsblock_zero(ip, &imap); goto error_out; } *ret_imap = imap; *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, - (unsigned long long)ret_imap->br_startblock, - (unsigned long long)ret_imap->br_startoff, - (unsigned long long)ret_imap->br_blockcount, - ret_imap->br_state); - } return 0; error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ @@ -715,17 +726,8 @@ retry: goto retry; } - 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, - (unsigned long long)ret_imap->br_startblock, - (unsigned long long)ret_imap->br_startoff, - (unsigned long long)ret_imap->br_blockcount, - ret_imap->br_state); - } + if (unlikely(!imap[0].br_startblock && !(io->io_flags & XFS_IOCORE_RT))) + return xfs_cmn_err_fsblock_zero(ip, &imap[0]); *ret_imap = imap[0]; *nmaps = 1; @@ -853,24 +855,10 @@ xfs_iomap_write_allocate( * See if we were able to allocate an extent that * covers at least part of the callers request */ - 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, - (unsigned long long) - imap[i].br_startblock, - (unsigned long long) - imap[i].br_startoff, - (unsigned long long) - imap[i].br_blockcount, - imap[i].br_state); - } + if (unlikely(!imap[i].br_startblock && + !(io->io_flags & XFS_IOCORE_RT))) + return xfs_cmn_err_fsblock_zero(ip, &imap[i]); if ((offset_fsb >= imap[i].br_startoff) && (offset_fsb < (imap[i].br_startoff + imap[i].br_blockcount))) { @@ -941,7 +929,7 @@ xfs_iomap_write_unwritten( XFS_WRITE_LOG_COUNT); if (error) { xfs_trans_cancel(tp, 0); - goto error0; + return XFS_ERROR(error); } xfs_ilock(ip, XFS_ILOCK_EXCL); @@ -967,19 +955,11 @@ xfs_iomap_write_unwritten( error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 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, - (unsigned long long)imap.br_startblock, - (unsigned long long)imap.br_startoff, - (unsigned long long)imap.br_blockcount, - imap.br_state); - } + return XFS_ERROR(error); + + if (unlikely(!imap.br_startblock && + !(io->io_flags & XFS_IOCORE_RT))) + return xfs_cmn_err_fsblock_zero(ip, &imap); if ((numblks_fsb = imap.br_blockcount) == 0) { /* @@ -999,6 +979,5 @@ error_on_bmapi_transaction: xfs_bmap_cancel(&free_list); xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT)); xfs_iunlock(ip, XFS_ILOCK_EXCL); -error0: return XFS_ERROR(error); } -- cgit v1.2.3 From 77e4635ae191774526ed695482a151ac986f3806 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:03:27 +1000 Subject: [XFS] Add a greedy allocation interface, allocating within a min/max size range. SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26803a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/kmem.c | 16 ++++++++++++++++ fs/xfs/linux-2.6/kmem.h | 3 ++- fs/xfs/quota/xfs_qm.c | 13 ++++++------- fs/xfs/xfs_iget.c | 17 ++++++++--------- fs/xfs/xfs_itable.c | 16 ++-------------- 5 files changed, 34 insertions(+), 31 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c index f77fe5c8fcc..80b9340488e 100644 --- a/fs/xfs/linux-2.6/kmem.c +++ b/fs/xfs/linux-2.6/kmem.c @@ -68,6 +68,22 @@ kmem_zalloc(size_t size, unsigned int __nocast flags) return ptr; } +void * +kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize, + unsigned int __nocast flags) +{ + void *ptr; + + while (!(ptr = kmem_zalloc(maxsize, flags))) { + if ((maxsize >>= 1) <= minsize) { + maxsize = minsize; + flags = KM_SLEEP; + } + } + *size = maxsize; + return ptr; +} + void kmem_free(void *ptr, size_t size) { diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h index 6d24274fb3c..9ebabdf7829 100644 --- a/fs/xfs/linux-2.6/kmem.h +++ b/fs/xfs/linux-2.6/kmem.h @@ -55,8 +55,9 @@ kmem_flags_convert(unsigned int __nocast flags) } extern void *kmem_alloc(size_t, unsigned int __nocast); -extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast); extern void *kmem_zalloc(size_t, unsigned int __nocast); +extern void *kmem_zalloc_greedy(size_t *, size_t, size_t, unsigned int __nocast); +extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast); extern void kmem_free(void *, size_t); /* diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 3f86c7c0464..8b2c6cf2c84 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -112,17 +112,16 @@ xfs_Gqm_init(void) { xfs_dqhash_t *udqhash, *gdqhash; xfs_qm_t *xqm; - uint i, hsize, flags = KM_SLEEP | KM_MAYFAIL | KM_LARGE; + uint i, hsize; /* * Initialize the dquot hash tables. */ - hsize = XFS_QM_HASHSIZE_HIGH; - while (!(udqhash = kmem_zalloc(hsize * sizeof(*udqhash), flags))) { - if ((hsize >>= 1) <= XFS_QM_HASHSIZE_LOW) - flags = KM_SLEEP; - } - gdqhash = kmem_zalloc(hsize * sizeof(*gdqhash), KM_SLEEP | KM_LARGE); + udqhash = kmem_zalloc_greedy(&hsize, + XFS_QM_HASHSIZE_LOW, XFS_QM_HASHSIZE_HIGH, + KM_SLEEP | KM_MAYFAIL | KM_LARGE); + gdqhash = kmem_zalloc(hsize, KM_SLEEP | KM_LARGE); + hsize /= sizeof(xfs_dqhash_t); ndquot = hsize << 8; xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP); diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 30eebc2fd90..e304ab07827 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -50,7 +50,7 @@ void xfs_ihash_init(xfs_mount_t *mp) { __uint64_t icount; - uint i, flags = KM_SLEEP | KM_MAYFAIL | KM_LARGE; + uint i; if (!mp->m_ihsize) { icount = mp->m_maxicount ? mp->m_maxicount : @@ -61,14 +61,13 @@ xfs_ihash_init(xfs_mount_t *mp) (64 * NBPP) / sizeof(xfs_ihash_t)); } - while (!(mp->m_ihash = (xfs_ihash_t *)kmem_zalloc(mp->m_ihsize * - sizeof(xfs_ihash_t), flags))) { - if ((mp->m_ihsize >>= 1) <= NBPP) - flags = KM_SLEEP; - } - for (i = 0; i < mp->m_ihsize; i++) { + mp->m_ihash = kmem_zalloc_greedy(&mp->m_ihsize, + NBPC * sizeof(xfs_ihash_t), + mp->m_ihsize * sizeof(xfs_ihash_t), + KM_SLEEP | KM_MAYFAIL | KM_LARGE); + mp->m_ihsize /= sizeof(xfs_ihash_t); + for (i = 0; i < mp->m_ihsize; i++) rwlock_init(&(mp->m_ihash[i].ih_lock)); - } } /* @@ -77,7 +76,7 @@ xfs_ihash_init(xfs_mount_t *mp) void xfs_ihash_free(xfs_mount_t *mp) { - kmem_free(mp->m_ihash, mp->m_ihsize*sizeof(xfs_ihash_t)); + kmem_free(mp->m_ihash, mp->m_ihsize * sizeof(xfs_ihash_t)); mp->m_ihash = NULL; } diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 61268994065..0fbbd7b9c69 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -326,7 +326,6 @@ xfs_bulkstat( int i; /* loop index */ int icount; /* count of inodes good in irbuf */ int irbsize; /* size of irec buffer in bytes */ - unsigned int kmflags; /* flags for allocating irec buffer */ xfs_ino_t ino; /* inode number (filesystem) */ xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */ xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ @@ -371,19 +370,8 @@ xfs_bulkstat( (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog); nimask = ~(nicluster - 1); nbcluster = nicluster >> mp->m_sb.sb_inopblog; - /* - * Allocate a local buffer for inode cluster btree records. - * This caps our maximum readahead window (so don't be stingy) - * but we must handle the case where we can't get a contiguous - * multi-page buffer, so we drop back toward pagesize; the end - * case we ensure succeeds, via appropriate allocation flags. - */ - irbsize = NBPP * 4; - kmflags = KM_SLEEP | KM_MAYFAIL; - while (!(irbuf = kmem_alloc(irbsize, kmflags))) { - if ((irbsize >>= 1) <= NBPP) - kmflags = KM_SLEEP; - } + irbuf = kmem_zalloc_greedy(&irbsize, NBPC, NBPC * 4, + KM_SLEEP | KM_MAYFAIL | KM_LARGE); nirbuf = irbsize / sizeof(*irbuf); /* -- cgit v1.2.3 From b627259c602f3f1b995d09aad2b57bed889430b9 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:03:33 +1000 Subject: [XFS] Remove a no-longer-correct debug assert from dio completion handling. SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26804a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_aops.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 7cde30d2939..09360cf1e1f 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -1356,7 +1356,6 @@ xfs_end_io_direct( ioend->io_size = size; xfs_finish_ioend(ioend); } else { - ASSERT(size >= 0); xfs_destroy_ioend(ioend); } -- cgit v1.2.3 From d432c80e68e3c283fc9a85021f5b65e0aabf254e Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:03:44 +1000 Subject: [XFS] Minor code rearranging and cleanup to prevent some coverity false positives. SGI-PV: 955502 SGI-Modid: xfs-linux-melb:xfs-kern:26805a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_alloc.c | 4 +++- fs/xfs/xfs_da_btree.c | 33 ++++++++++++++++++--------------- fs/xfs/xfs_rtalloc.c | 36 +++++++++++++++--------------------- 3 files changed, 36 insertions(+), 37 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 879aa38ddd2..e80dda3437d 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -1477,8 +1477,10 @@ xfs_alloc_ag_vextent_small( /* * Can't allocate from the freelist for some reason. */ - else + else { + fbno = NULLAGBLOCK; flen = 0; + } /* * Can't do the allocation, give up. */ diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 32ab61d17ac..a68bc1f1a31 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c @@ -1054,7 +1054,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) xfs_da_node_entry_t *btree; xfs_dablk_t blkno; int probe, span, max, error, retval; - xfs_dahash_t hashval; + xfs_dahash_t hashval, btreehashval; xfs_da_args_t *args; args = state->args; @@ -1079,30 +1079,32 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) return(error); } curr = blk->bp->data; - ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || - be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC || - be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); + blk->magic = be16_to_cpu(curr->magic); + ASSERT(blk->magic == XFS_DA_NODE_MAGIC || + blk->magic == XFS_DIR2_LEAFN_MAGIC || + blk->magic == XFS_ATTR_LEAF_MAGIC); /* * Search an intermediate node for a match. */ - blk->magic = be16_to_cpu(curr->magic); if (blk->magic == XFS_DA_NODE_MAGIC) { node = blk->bp->data; - blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval); + max = be16_to_cpu(node->hdr.count); + btreehashval = node->btree[max-1].hashval; + blk->hashval = be32_to_cpu(btreehashval); /* * Binary search. (note: small blocks will skip loop) */ - max = be16_to_cpu(node->hdr.count); probe = span = max / 2; hashval = args->hashval; for (btree = &node->btree[probe]; span > 4; btree = &node->btree[probe]) { span /= 2; - if (be32_to_cpu(btree->hashval) < hashval) + btreehashval = be32_to_cpu(btree->hashval); + if (btreehashval < hashval) probe += span; - else if (be32_to_cpu(btree->hashval) > hashval) + else if (btreehashval > hashval) probe -= span; else break; @@ -1133,10 +1135,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) blk->index = probe; blkno = be32_to_cpu(btree->before); } - } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) { + } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); break; - } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) { + } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); break; } @@ -1152,11 +1154,13 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { retval = xfs_dir2_leafn_lookup_int(blk->bp, args, &blk->index, state); - } - else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { + } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { retval = xfs_attr_leaf_lookup_int(blk->bp, args); blk->index = args->index; args->blkno = blk->blkno; + } else { + ASSERT(0); + return XFS_ERROR(EFSCORRUPTED); } if (((retval == ENOENT) || (retval == ENOATTR)) && (blk->hashval == args->hashval)) { @@ -1166,8 +1170,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) return(error); if (retval == 0) { continue; - } - else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { + } else if (blk->magic == XFS_ATTR_LEAF_MAGIC) { /* path_shift() gives ENOENT */ retval = XFS_ERROR(ENOATTR); } diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 5a0b678956e..e050987afe1 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1976,7 +1976,10 @@ xfs_growfs_rt( if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks, mp->m_sb.sb_rsumino))) return error; - nmp = NULL; + /* + * Allocate a new (fake) mount/sb. + */ + nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP); /* * Loop over the bitmap blocks. * We will do everything one bitmap block at a time. @@ -1987,10 +1990,6 @@ xfs_growfs_rt( ((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0); bmbno < nrbmblocks; bmbno++) { - /* - * Allocate a new (fake) mount/sb. - */ - nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP); *nmp = *mp; nsbp = &nmp->m_sb; /* @@ -2018,13 +2017,13 @@ xfs_growfs_rt( cancelflags = 0; if ((error = xfs_trans_reserve(tp, 0, XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0))) - goto error_exit; + break; /* * Lock out other callers by grabbing the bitmap inode lock. */ if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip))) - goto error_exit; + break; ASSERT(ip == mp->m_rbmip); /* * Update the bitmap inode's size. @@ -2038,7 +2037,7 @@ xfs_growfs_rt( */ if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0, XFS_ILOCK_EXCL, &ip))) - goto error_exit; + break; ASSERT(ip == mp->m_rsumip); /* * Update the summary inode's size. @@ -2053,7 +2052,7 @@ xfs_growfs_rt( mp->m_rsumlevels != nmp->m_rsumlevels) { error = xfs_rtcopy_summary(mp, nmp, tp); if (error) - goto error_exit; + break; } /* * Update superblock fields. @@ -2080,17 +2079,12 @@ xfs_growfs_rt( error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents, nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno); if (error) - goto error_exit; + break; /* * Mark more blocks free in the superblock. */ xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, nsbp->sb_rextents - sbp->sb_rextents); - /* - * Free the fake mp structure. - */ - kmem_free(nmp, sizeof(*nmp)); - nmp = NULL; /* * Update mp values into the real mp structure. */ @@ -2101,15 +2095,15 @@ xfs_growfs_rt( */ xfs_trans_commit(tp, 0, NULL); } - return 0; + + if (error) + xfs_trans_cancel(tp, cancelflags); /* - * Error paths come here. + * Free the fake mp structure. */ -error_exit: - if (nmp) - kmem_free(nmp, sizeof(*nmp)); - xfs_trans_cancel(tp, cancelflags); + kmem_free(nmp, sizeof(*nmp)); + return error; } -- cgit v1.2.3 From 68c3271515f11f6665dc8732e53aaab3d3fdd7d3 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:03:53 +1000 Subject: [XFS] Fix a porting botch on the realtime subvol growfs code path. SGI-PV: 955515 SGI-Modid: xfs-linux-melb:xfs-kern:26806a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_linux.h | 7 +++++++ fs/xfs/xfs_rtalloc.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 14d840208e8..2b0e0018738 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h @@ -332,4 +332,11 @@ static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y) return(x * y); } +static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y) +{ + x += y - 1; + do_div(x, y); + return x; +} + #endif /* __XFS_LINUX__ */ diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index e050987afe1..880c73271c0 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -1948,7 +1948,7 @@ xfs_growfs_rt( */ nrextents = nrblocks; do_div(nrextents, in->extsize); - nrbmblocks = roundup_64(nrextents, NBBY * sbp->sb_blocksize); + nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize); nrextslog = xfs_highbit32(nrextents); nrsumlevels = nrextslog + 1; nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks; -- cgit v1.2.3 From 22d91f65d57a7f1a1c5fc81f47b47b0cc54ad6f7 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 28 Sep 2006 11:04:07 +1000 Subject: [XFS] Add lock annotations to xfs_trans_update_ail and xfs_trans_delete_ail xfs_trans_update_ail and xfs_trans_delete_ail get called with the AIL lock held, and release it. Add lock annotations to these two functions so that sparse can check callers for lock pairing, and so that sparse will not complain about these functions since they intentionally use locks in this manner. SGI-PV: 954580 SGI-Modid: xfs-linux-melb:xfs-kern:26807a Signed-off-by: Josh Triplett Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_trans_ail.c | 4 ++-- fs/xfs/xfs_trans_priv.h | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 558c87ff0c4..fc39b166d40 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -276,7 +276,7 @@ xfs_trans_update_ail( xfs_mount_t *mp, xfs_log_item_t *lip, xfs_lsn_t lsn, - unsigned long s) + unsigned long s) __releases(mp->m_ail_lock) { xfs_ail_entry_t *ailp; xfs_log_item_t *dlip=NULL; @@ -328,7 +328,7 @@ void xfs_trans_delete_ail( xfs_mount_t *mp, xfs_log_item_t *lip, - unsigned long s) + unsigned long s) __releases(mp->m_ail_lock) { xfs_ail_entry_t *ailp; xfs_log_item_t *dlip; diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 13edab8a9e9..447ac4308c9 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h @@ -46,11 +46,13 @@ xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp, /* * From xfs_trans_ail.c */ -void xfs_trans_update_ail(struct xfs_mount *, - struct xfs_log_item *, xfs_lsn_t, - unsigned long); -void xfs_trans_delete_ail(struct xfs_mount *, - struct xfs_log_item *, unsigned long); +void xfs_trans_update_ail(struct xfs_mount *mp, + struct xfs_log_item *lip, xfs_lsn_t lsn, + unsigned long s) + __releases(mp->m_ail_lock); +void xfs_trans_delete_ail(struct xfs_mount *mp, + struct xfs_log_item *lip, unsigned long s) + __releases(mp->m_ail_lock); struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *); struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *, struct xfs_log_item *, int *, int *); -- cgit v1.2.3 From 955e47ad28b5b255ddcd7eb9cb814a269dc6e991 Mon Sep 17 00:00:00 2001 From: Tim Shimmin Date: Thu, 28 Sep 2006 11:04:16 +1000 Subject: [XFS] Fixes the leak in reservation space because we weren't ungranting space for the unmount record - which becomes a problem in the freeze/thaw scenario. SGI-PV: 942533 SGI-Modid: xfs-linux-melb:xfs-kern:26815a Signed-off-by: Tim Shimmin --- fs/xfs/xfs_log.c | 8 ++++++-- fs/xfs/xfs_log_priv.h | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index ac999789a44..c48bf61f17b 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -617,7 +617,8 @@ xfs_log_unmount_write(xfs_mount_t *mp) reg[0].i_len = sizeof(magic); XLOG_VEC_SET_TYPE(®[0], XLOG_REG_TYPE_UNMOUNT); - error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0, 0); + error = xfs_log_reserve(mp, 600, 1, &tic, + XFS_LOG, 0, XLOG_UNMOUNT_REC_TYPE); if (!error) { /* remove inited flag */ ((xlog_ticket_t *)tic)->t_flags = 0; @@ -655,8 +656,11 @@ xfs_log_unmount_write(xfs_mount_t *mp) } else { LOG_UNLOCK(log, s); } - if (tic) + if (tic) { + xlog_trace_loggrant(log, tic, "unmount rec"); + xlog_ungrant_log_space(log, tic); xlog_state_put_ticket(log, tic); + } } else { /* * We're already in forced_shutdown mode, couldn't diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 7bf5046d8d2..9bd3cdf11a8 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -502,6 +502,12 @@ extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *); #define XLOG_TRACE_SLEEP_FLUSH 3 #define XLOG_TRACE_WAKE_FLUSH 4 +/* + * Unmount record type is used as a pseudo transaction type for the ticket. + * It's value must be outside the range of XFS_TRANS_* values. + */ +#define XLOG_UNMOUNT_REC_TYPE (-1U) + #endif /* __KERNEL__ */ #endif /* __XFS_LOG_PRIV_H__ */ -- cgit v1.2.3 From 22de606a0b9623bf15752808f123848a65a6cc28 Mon Sep 17 00:00:00 2001 From: Vlad Apostolov Date: Thu, 28 Sep 2006 11:04:24 +1000 Subject: [XFS] pv 955157, rv bnaujok - break the loop on formatter() error SGI-PV: 955157 SGI-Modid: xfs-linux-melb:xfs-kern:26866a Signed-off-by: Vlad Apostolov Signed-off-by: Tim Shimmin --- fs/xfs/xfs_itable.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'fs') diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 0fbbd7b9c69..b9edbc65f36 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -637,6 +637,11 @@ xfs_bulkstat( if (fmterror == BULKSTAT_RV_NOTHING) { if (error == ENOMEM) ubleft = 0; + else if (error) { + ubleft = 0; + rval = error; + break; + } continue; } if (fmterror == BULKSTAT_RV_GIVEUP) { -- cgit v1.2.3 From e132f54ce8660bbf34723cc12cb11e6f61d6fbac Mon Sep 17 00:00:00 2001 From: Vlad Apostolov Date: Thu, 28 Sep 2006 11:04:31 +1000 Subject: [XFS] pv 955157, rv bnaujok - break the loop on EFAULT formatter() error SGI-PV: 955157 SGI-Modid: xfs-linux-melb:xfs-kern:26869a Signed-off-by: Vlad Apostolov Signed-off-by: Tim Shimmin --- fs/xfs/xfs_itable.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index b9edbc65f36..e338d6cf027 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -635,13 +635,13 @@ xfs_bulkstat( ubleft, private_data, bno, &ubused, dip, &fmterror); if (fmterror == BULKSTAT_RV_NOTHING) { - if (error == ENOMEM) - ubleft = 0; - else if (error) { + if (error == EFAULT) { ubleft = 0; rval = error; break; } + else if (error == ENOMEM) + ubleft = 0; continue; } if (fmterror == BULKSTAT_RV_GIVEUP) { -- cgit v1.2.3 From 215101c36012399cf2eaee849de54eeefc9f618c Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:04:43 +1000 Subject: [XFS] Fix kmem_zalloc_greedy warnings on 64 bit platforms. SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26907a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/quota/xfs_qm.c | 3 ++- fs/xfs/xfs_itable.c | 2 +- fs/xfs/xfs_mount.h | 2 +- fs/xfs/xfs_vfsops.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 8b2c6cf2c84..7c6a3a50379 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c @@ -112,7 +112,8 @@ xfs_Gqm_init(void) { xfs_dqhash_t *udqhash, *gdqhash; xfs_qm_t *xqm; - uint i, hsize; + size_t hsize; + uint i; /* * Initialize the dquot hash tables. diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index e338d6cf027..b608b8ab1dd 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -325,7 +325,7 @@ xfs_bulkstat( xfs_agino_t gino; /* current btree rec's start inode */ int i; /* loop index */ int icount; /* count of inodes good in irbuf */ - int irbsize; /* size of irec buffer in bytes */ + size_t irbsize; /* size of irec buffer in bytes */ xfs_ino_t ino; /* inode number (filesystem) */ xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */ xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 3091c44f29e..e5f396ff9a3 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -331,7 +331,7 @@ typedef struct xfs_mount { xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */ lock_t m_agirotor_lock;/* .. and lock protecting it */ xfs_agnumber_t m_maxagi; /* highest inode alloc group */ - uint m_ihsize; /* size of next field */ + size_t m_ihsize; /* size of next field */ struct xfs_ihash *m_ihash; /* fs private inode hash table*/ struct xfs_inode *m_inodes; /* active inode list */ struct list_head m_del_inodes; /* inodes to reclaim */ diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index a34796e57af..62336a4cc5a 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c @@ -1922,7 +1922,7 @@ xfs_showargs( } if (mp->m_flags & XFS_MOUNT_IHASHSIZE) - seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize); + seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", (int)mp->m_ihsize); if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk", -- cgit v1.2.3 From edcd4bce5e58987c8c039bdf7705a22cd229fe96 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 28 Sep 2006 11:05:33 +1000 Subject: [XFS] Minor cleanup from dio locking fix, remove an extra conditional. SGI-PV: 955696 SGI-Modid: xfs-linux-melb:xfs-kern:26908a Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_lrw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index ee788b1cb36..55992b40353 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -270,12 +270,12 @@ xfs_read( } } - if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp))) - bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), - -1, FI_REMAPF_LOCKED); - - if (unlikely(ioflags & IO_ISDIRECT)) + if (unlikely(ioflags & IO_ISDIRECT)) { + if (VN_CACHED(vp)) + bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)), + -1, FI_REMAPF_LOCKED); mutex_unlock(&inode->i_mutex); + } xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, (void *)iovp, segs, *offset, ioflags); -- cgit v1.2.3 From 91d87232044c1ceb8371625c27479e982984a848 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 28 Sep 2006 11:05:40 +1000 Subject: [XFS] Reduce endian flipping in alloc_btree, same as was done for ialloc_btree. SGI-PV: 955302 SGI-Modid: xfs-linux-melb:xfs-kern:26910a Signed-off-by: Eric Sandeen Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/xfs_alloc_btree.c | 108 +++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 51 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 500a1d75403..74cadf95d4e 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -92,6 +92,7 @@ xfs_alloc_delrec( xfs_alloc_key_t *rkp; /* right block key pointer */ xfs_alloc_ptr_t *rpp; /* right block address pointer */ int rrecs=0; /* number of records in right block */ + int numrecs; xfs_alloc_rec_t *rrp; /* right block record pointer */ xfs_btree_cur_t *tcur; /* temporary btree cursor */ @@ -115,7 +116,8 @@ xfs_alloc_delrec( /* * Fail if we're off the end of the block. */ - if (ptr > be16_to_cpu(block->bb_numrecs)) { + numrecs = be16_to_cpu(block->bb_numrecs); + if (ptr > numrecs) { *stat = 0; return 0; } @@ -129,18 +131,18 @@ xfs_alloc_delrec( lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur); lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur); #ifdef DEBUG - for (i = ptr; i < be16_to_cpu(block->bb_numrecs); i++) { + for (i = ptr; i < numrecs; i++) { if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level))) return error; } #endif - if (ptr < be16_to_cpu(block->bb_numrecs)) { + if (ptr < numrecs) { memmove(&lkp[ptr - 1], &lkp[ptr], - (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lkp)); + (numrecs - ptr) * sizeof(*lkp)); memmove(&lpp[ptr - 1], &lpp[ptr], - (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lpp)); - xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1); - xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1); + (numrecs - ptr) * sizeof(*lpp)); + xfs_alloc_log_ptrs(cur, bp, ptr, numrecs - 1); + xfs_alloc_log_keys(cur, bp, ptr, numrecs - 1); } } /* @@ -149,10 +151,10 @@ xfs_alloc_delrec( */ else { lrp = XFS_ALLOC_REC_ADDR(block, 1, cur); - if (ptr < be16_to_cpu(block->bb_numrecs)) { + if (ptr < numrecs) { memmove(&lrp[ptr - 1], &lrp[ptr], - (be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lrp)); - xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1); + (numrecs - ptr) * sizeof(*lrp)); + xfs_alloc_log_recs(cur, bp, ptr, numrecs - 1); } /* * If it's the first record in the block, we'll need a key @@ -167,7 +169,8 @@ xfs_alloc_delrec( /* * Decrement and log the number of entries in the block. */ - be16_add(&block->bb_numrecs, -1); + numrecs--; + block->bb_numrecs = cpu_to_be16(numrecs); xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS); /* * See if the longest free extent in the allocation group was @@ -181,14 +184,14 @@ xfs_alloc_delrec( if (level == 0 && cur->bc_btnum == XFS_BTNUM_CNT && be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK && - ptr > be16_to_cpu(block->bb_numrecs)) { - ASSERT(ptr == be16_to_cpu(block->bb_numrecs) + 1); + ptr > numrecs) { + ASSERT(ptr == numrecs + 1); /* * There are still records in the block. Grab the size * from the last one. */ - if (be16_to_cpu(block->bb_numrecs)) { - rrp = XFS_ALLOC_REC_ADDR(block, be16_to_cpu(block->bb_numrecs), cur); + if (numrecs) { + rrp = XFS_ALLOC_REC_ADDR(block, numrecs, cur); agf->agf_longest = rrp->ar_blockcount; } /* @@ -211,7 +214,7 @@ xfs_alloc_delrec( * and it's NOT the leaf level, * then we can get rid of this level. */ - if (be16_to_cpu(block->bb_numrecs) == 1 && level > 0) { + if (numrecs == 1 && level > 0) { /* * lpp is still set to the first pointer in the block. * Make it the new root of the btree. @@ -267,7 +270,7 @@ xfs_alloc_delrec( * If the number of records remaining in the block is at least * the minimum, we're done. */ - if (be16_to_cpu(block->bb_numrecs) >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) { + if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) { if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i))) return error; *stat = 1; @@ -419,19 +422,21 @@ xfs_alloc_delrec( * See if we can join with the left neighbor block. */ if (lbno != NULLAGBLOCK && - lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { + lrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { /* * Set "right" to be the starting block, * "left" to be the left neighbor. */ rbno = bno; right = block; + rrecs = be16_to_cpu(right->bb_numrecs); rbp = bp; if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, cur->bc_private.a.agno, lbno, 0, &lbp, XFS_ALLOC_BTREE_REF))) return error; left = XFS_BUF_TO_ALLOC_BLOCK(lbp); + lrecs = be16_to_cpu(left->bb_numrecs); if ((error = xfs_btree_check_sblock(cur, left, level, lbp))) return error; } @@ -439,20 +444,21 @@ xfs_alloc_delrec( * If that won't work, see if we can join with the right neighbor block. */ else if (rbno != NULLAGBLOCK && - rrecs + be16_to_cpu(block->bb_numrecs) <= - XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { + rrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { /* * Set "left" to be the starting block, * "right" to be the right neighbor. */ lbno = bno; left = block; + lrecs = be16_to_cpu(left->bb_numrecs); lbp = bp; if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, cur->bc_private.a.agno, rbno, 0, &rbp, XFS_ALLOC_BTREE_REF))) return error; right = XFS_BUF_TO_ALLOC_BLOCK(rbp); + rrecs = be16_to_cpu(right->bb_numrecs); if ((error = xfs_btree_check_sblock(cur, right, level, rbp))) return error; } @@ -474,34 +480,28 @@ xfs_alloc_delrec( /* * It's a non-leaf. Move keys and pointers. */ - lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur); - lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur); + lkp = XFS_ALLOC_KEY_ADDR(left, lrecs + 1, cur); + lpp = XFS_ALLOC_PTR_ADDR(left, lrecs + 1, cur); rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur); rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur); #ifdef DEBUG - for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) { + for (i = 0; i < rrecs; i++) { if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level))) return error; } #endif - memcpy(lkp, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*lkp)); - memcpy(lpp, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*lpp)); - xfs_alloc_log_keys(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1, - be16_to_cpu(left->bb_numrecs) + - be16_to_cpu(right->bb_numrecs)); - xfs_alloc_log_ptrs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1, - be16_to_cpu(left->bb_numrecs) + - be16_to_cpu(right->bb_numrecs)); + memcpy(lkp, rkp, rrecs * sizeof(*lkp)); + memcpy(lpp, rpp, rrecs * sizeof(*lpp)); + xfs_alloc_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs); + xfs_alloc_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs); } else { /* * It's a leaf. Move records. */ - lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur); + lrp = XFS_ALLOC_REC_ADDR(left, lrecs + 1, cur); rrp = XFS_ALLOC_REC_ADDR(right, 1, cur); - memcpy(lrp, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*lrp)); - xfs_alloc_log_recs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1, - be16_to_cpu(left->bb_numrecs) + - be16_to_cpu(right->bb_numrecs)); + memcpy(lrp, rrp, rrecs * sizeof(*lrp)); + xfs_alloc_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs); } /* * If we joined with the left neighbor, set the buffer in the @@ -509,7 +509,7 @@ xfs_alloc_delrec( */ if (bp != lbp) { xfs_btree_setbuf(cur, level, lbp); - cur->bc_ptrs[level] += be16_to_cpu(left->bb_numrecs); + cur->bc_ptrs[level] += lrecs; } /* * If we joined with the right neighbor and there's a level above @@ -521,7 +521,8 @@ xfs_alloc_delrec( /* * Fix up the number of records in the surviving block. */ - be16_add(&left->bb_numrecs, be16_to_cpu(right->bb_numrecs)); + lrecs += rrecs; + left->bb_numrecs = cpu_to_be16(lrecs); /* * Fix up the right block pointer in the surviving block, and log it. */ @@ -608,6 +609,7 @@ xfs_alloc_insrec( xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */ xfs_alloc_key_t nkey; /* new key value, from split */ xfs_alloc_rec_t nrec; /* new record value, for caller */ + int numrecs; int optr; /* old ptr value */ xfs_alloc_ptr_t *pp; /* pointer to btree addresses */ int ptr; /* index in btree block for this rec */ @@ -653,13 +655,14 @@ xfs_alloc_insrec( */ bp = cur->bc_bufs[level]; block = XFS_BUF_TO_ALLOC_BLOCK(bp); + numrecs = be16_to_cpu(block->bb_numrecs); #ifdef DEBUG if ((error = xfs_btree_check_sblock(cur, block, level, bp))) return error; /* * Check that the new entry is being inserted in the right place. */ - if (ptr <= be16_to_cpu(block->bb_numrecs)) { + if (ptr <= numrecs) { if (level == 0) { rp = XFS_ALLOC_REC_ADDR(block, ptr, cur); xfs_btree_check_rec(cur->bc_btnum, recp, rp); @@ -675,7 +678,7 @@ xfs_alloc_insrec( * If the block is full, we can't insert the new entry until we * make the block un-full. */ - if (be16_to_cpu(block->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { + if (numrecs == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) { /* * First, try shifting an entry to the right neighbor. */ @@ -729,6 +732,7 @@ xfs_alloc_insrec( * At this point we know there's room for our new entry in the block * we're pointing at. */ + numrecs = be16_to_cpu(block->bb_numrecs); if (level > 0) { /* * It's a non-leaf entry. Make a hole for the new data @@ -737,15 +741,15 @@ xfs_alloc_insrec( kp = XFS_ALLOC_KEY_ADDR(block, 1, cur); pp = XFS_ALLOC_PTR_ADDR(block, 1, cur); #ifdef DEBUG - for (i = be16_to_cpu(block->bb_numrecs); i >= ptr; i--) { + for (i = numrecs; i >= ptr; i--) { if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level))) return error; } #endif memmove(&kp[ptr], &kp[ptr - 1], - (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*kp)); + (numrecs - ptr + 1) * sizeof(*kp)); memmove(&pp[ptr], &pp[ptr - 1], - (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*pp)); + (numrecs - ptr + 1) * sizeof(*pp)); #ifdef DEBUG if ((error = xfs_btree_check_sptr(cur, *bnop, level))) return error; @@ -755,11 +759,12 @@ xfs_alloc_insrec( */ kp[ptr - 1] = key; pp[ptr - 1] = cpu_to_be32(*bnop); - be16_add(&block->bb_numrecs, 1); - xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); - xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); + numrecs++; + block->bb_numrecs = cpu_to_be16(numrecs); + xfs_alloc_log_keys(cur, bp, ptr, numrecs); + xfs_alloc_log_ptrs(cur, bp, ptr, numrecs); #ifdef DEBUG - if (ptr < be16_to_cpu(block->bb_numrecs)) + if (ptr < numrecs) xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1, kp + ptr); #endif @@ -769,16 +774,17 @@ xfs_alloc_insrec( */ rp = XFS_ALLOC_REC_ADDR(block, 1, cur); memmove(&rp[ptr], &rp[ptr - 1], - (be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*rp)); + (numrecs - ptr + 1) * sizeof(*rp)); /* * Now stuff the new record in, bump numrecs * and log the new data. */ rp[ptr - 1] = *recp; - be16_add(&block->bb_numrecs, 1); - xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs)); + numrecs++; + block->bb_numrecs = cpu_to_be16(numrecs); + xfs_alloc_log_recs(cur, bp, ptr, numrecs); #ifdef DEBUG - if (ptr < be16_to_cpu(block->bb_numrecs)) + if (ptr < numrecs) xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1, rp + ptr); #endif -- cgit v1.2.3 From 7ae67d78e7518fba89e5f3a74bdcb68e48ae8858 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 28 Sep 2006 11:05:46 +1000 Subject: [XFS] standardize on one sema init macro One sema to rule them all, one sema to find them... SGI-PV: 907752 SGI-Modid: xfs-linux-melb:xfs-kern:26911a Signed-off-by: Eric Sandeen Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/sema.h | 2 -- fs/xfs/xfs_iget.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/sema.h b/fs/xfs/linux-2.6/sema.h index b25090094cc..2009e6d922c 100644 --- a/fs/xfs/linux-2.6/sema.h +++ b/fs/xfs/linux-2.6/sema.h @@ -29,8 +29,6 @@ typedef struct semaphore sema_t; -#define init_sema(sp, val, c, d) sema_init(sp, val) -#define initsema(sp, val) sema_init(sp, val) #define initnsema(sp, val, name) sema_init(sp, val) #define psema(sp, b) down(sp) #define vsema(sp) up(sp) diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index e304ab07827..9b9379792f3 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -546,7 +546,7 @@ xfs_inode_lock_init( mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number); init_waitqueue_head(&ip->i_ipin_wait); atomic_set(&ip->i_pincount, 0); - init_sema(&ip->i_flock, 1, "xfsfino", vp->v_number); + initnsema(&ip->i_flock, 1, "xfsfino"); } /* -- cgit v1.2.3 From 01106eae97b70399ce5a273a3cceb5246e8d9cc8 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 28 Sep 2006 11:05:52 +1000 Subject: [XFS] Collapse sv_init and init_sv into just the one interface. SGI-PV: 907752 SGI-Modid: xfs-linux-melb:xfs-kern:26925a Signed-off-by: Eric Sandeen Signed-off-by: Nathan Scott Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/sv.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/sv.h b/fs/xfs/linux-2.6/sv.h index 9a8ad481b00..351a8f454bd 100644 --- a/fs/xfs/linux-2.6/sv.h +++ b/fs/xfs/linux-2.6/sv.h @@ -53,8 +53,6 @@ static inline void _sv_wait(sv_t *sv, spinlock_t *lock, int state, remove_wait_queue(&sv->waiters, &wait); } -#define init_sv(sv,type,name,flag) \ - init_waitqueue_head(&(sv)->waiters) #define sv_init(sv,flag,name) \ init_waitqueue_head(&(sv)->waiters) #define sv_destroy(sv) \ -- cgit v1.2.3 From f273ab848b7cbc0088b0ac7457b3769e6566074e Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 28 Sep 2006 11:06:03 +1000 Subject: [XFS] Really fix use after free in xfs_iunpin. The previous attempts to fix the linux inode use-after-free in xfs_iunpin simply made the problem harder to hit. We actually need complete exclusion between xfs_reclaim and xfs_iunpin, as well as ensuring that the i_flags are consistent during both of these functions. Introduce a new spinlock for exclusion and the i_flags, and fix up xfs_iunpin to use igrab before marking the inode dirty. SGI-PV: 952967 SGI-Modid: xfs-linux-melb:xfs-kern:26964a Signed-off-by: David Chinner Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/xfs_super.c | 2 ++ fs/xfs/xfs_iget.c | 6 ++++++ fs/xfs/xfs_inode.c | 23 ++++++++++++++++++++--- fs/xfs/xfs_inode.h | 1 + fs/xfs/xfs_itable.c | 1 + fs/xfs/xfs_vnodeops.c | 5 +++++ 6 files changed, 35 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 9df9ed37d21..38c4d128a8c 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -227,7 +227,9 @@ xfs_initialize_vnode( xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip); xfs_set_inodeops(inode); + spin_lock(&ip->i_flags_lock); ip->i_flags &= ~XFS_INEW; + spin_unlock(&ip->i_flags_lock); barrier(); unlock_new_inode(inode); diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 9b9379792f3..b73d216ecaf 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -243,7 +243,9 @@ again: XFS_STATS_INC(xs_ig_found); + spin_lock(&ip->i_flags_lock); ip->i_flags &= ~XFS_IRECLAIMABLE; + spin_unlock(&ip->i_flags_lock); version = ih->ih_version; read_unlock(&ih->ih_lock); xfs_ihash_promote(ih, ip, version); @@ -297,7 +299,9 @@ finish_inode: if (lock_flags != 0) xfs_ilock(ip, lock_flags); + spin_lock(&ip->i_flags_lock); ip->i_flags &= ~XFS_ISTALE; + spin_unlock(&ip->i_flags_lock); vn_trace_exit(vp, "xfs_iget.found", (inst_t *)__return_address); @@ -367,7 +371,9 @@ finish_inode: ih->ih_next = ip; ip->i_udquot = ip->i_gdquot = NULL; ih->ih_version++; + spin_lock(&ip->i_flags_lock); ip->i_flags |= XFS_INEW; + spin_unlock(&ip->i_flags_lock); write_unlock(&ih->ih_lock); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 66a78287a95..c27d7d495aa 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -867,6 +867,7 @@ xfs_iread( ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); ip->i_ino = ino; ip->i_mount = mp; + spin_lock_init(&ip->i_flags_lock); /* * Get pointer's to the on-disk inode and the buffer containing it. @@ -2214,7 +2215,9 @@ xfs_ifree_cluster( if (ip == free_ip) { if (xfs_iflock_nowait(ip)) { + spin_lock(&ip->i_flags_lock); ip->i_flags |= XFS_ISTALE; + spin_unlock(&ip->i_flags_lock); if (xfs_inode_clean(ip)) { xfs_ifunlock(ip); @@ -2228,7 +2231,9 @@ xfs_ifree_cluster( if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { if (xfs_iflock_nowait(ip)) { + spin_lock(&ip->i_flags_lock); ip->i_flags |= XFS_ISTALE; + spin_unlock(&ip->i_flags_lock); if (xfs_inode_clean(ip)) { xfs_ifunlock(ip); @@ -2258,7 +2263,9 @@ xfs_ifree_cluster( AIL_LOCK(mp,s); iip->ili_flush_lsn = iip->ili_item.li_lsn; AIL_UNLOCK(mp, s); + spin_lock(&iip->ili_inode->i_flags_lock); iip->ili_inode->i_flags |= XFS_ISTALE; + spin_unlock(&iip->ili_inode->i_flags_lock); pre_flushed++; } lip = lip->li_bio_list; @@ -2754,19 +2761,29 @@ xfs_iunpin( * call as the inode reclaim may be blocked waiting for * the inode to become unpinned. */ + struct inode *inode = NULL; + + spin_lock(&ip->i_flags_lock); if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { bhv_vnode_t *vp = XFS_ITOV_NULL(ip); /* make sync come back and flush this inode */ if (vp) { - struct inode *inode = vn_to_inode(vp); + inode = vn_to_inode(vp); if (!(inode->i_state & - (I_NEW|I_FREEING|I_CLEAR))) - mark_inode_dirty_sync(inode); + (I_NEW|I_FREEING|I_CLEAR))) { + inode = igrab(inode); + if (inode) + mark_inode_dirty_sync(inode); + } else + inode = NULL; } } + spin_unlock(&ip->i_flags_lock); wake_up(&ip->i_ipin_wait); + if (inode) + iput(inode); } } diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index fdb89f72db9..e96eb0835fe 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -267,6 +267,7 @@ typedef struct xfs_inode { sema_t i_flock; /* inode flush lock */ atomic_t i_pincount; /* inode pin count */ wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */ + spinlock_t i_flags_lock; /* inode i_flags lock */ #ifdef HAVE_REFCACHE struct xfs_inode **i_refcache; /* ptr to entry in ref cache */ struct xfs_inode *i_release; /* inode to unref */ diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index b608b8ab1dd..136c6b06f1c 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -577,6 +577,7 @@ xfs_bulkstat( KM_SLEEP); ip->i_ino = ino; ip->i_mount = mp; + spin_lock_init(&ip->i_flags_lock); if (bp) xfs_buf_relse(bp); error = xfs_itobp(mp, NULL, ip, diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 1a6782eaf5d..061e2ffdd1d 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -3844,7 +3844,9 @@ xfs_reclaim( XFS_MOUNT_ILOCK(mp); vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); + spin_lock(&ip->i_flags_lock); ip->i_flags |= XFS_IRECLAIMABLE; + spin_unlock(&ip->i_flags_lock); XFS_MOUNT_IUNLOCK(mp); } return 0; @@ -3869,8 +3871,10 @@ xfs_finish_reclaim( * us. */ write_lock(&ih->ih_lock); + spin_lock(&ip->i_flags_lock); if ((ip->i_flags & XFS_IRECLAIM) || (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) { + spin_unlock(&ip->i_flags_lock); write_unlock(&ih->ih_lock); if (locked) { xfs_ifunlock(ip); @@ -3879,6 +3883,7 @@ xfs_finish_reclaim( return 1; } ip->i_flags |= XFS_IRECLAIM; + spin_unlock(&ip->i_flags_lock); write_unlock(&ih->ih_lock); /* -- cgit v1.2.3 From 6216ff18839bf302805f67c93e8bc344387c513b Mon Sep 17 00:00:00 2001 From: Vlad Apostolov Date: Thu, 28 Sep 2006 11:06:10 +1000 Subject: [XFS] pv 956240, author: nathans, rv: vapo - Minor fixes in kmem_zalloc_greedy() SGI-PV: 956240 SGI-Modid: xfs-linux-melb:xfs-kern:26983a Signed-off-by: Vlad Apostolov Signed-off-by: Tim Shimmin --- fs/xfs/linux-2.6/kmem.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'fs') diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c index 80b9340488e..d5973758981 100644 --- a/fs/xfs/linux-2.6/kmem.c +++ b/fs/xfs/linux-2.6/kmem.c @@ -72,15 +72,20 @@ void * kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize, unsigned int __nocast flags) { - void *ptr; + void *ptr; + size_t kmsize = maxsize; + unsigned int kmflags = (flags & ~KM_SLEEP) | KM_NOSLEEP; - while (!(ptr = kmem_zalloc(maxsize, flags))) { - if ((maxsize >>= 1) <= minsize) { - maxsize = minsize; - flags = KM_SLEEP; + while (!(ptr = kmem_zalloc(kmsize, kmflags))) { + if ((kmsize <= minsize) && (flags & KM_NOSLEEP)) + break; + if ((kmsize >>= 1) <= minsize) { + kmsize = minsize; + kmflags = flags; } } - *size = maxsize; + if (ptr) + *size = kmsize; return ptr; } -- cgit v1.2.3 From 6f1f21684078884b62cfff2ea80a1a6c07f79824 Mon Sep 17 00:00:00 2001 From: Vlad Apostolov Date: Thu, 28 Sep 2006 11:06:15 +1000 Subject: [XFS] pv 956241, author: nathans, rv: vapo - make ino validation checks consistent in bulkstat SGI-PV: 956241 SGI-Modid: xfs-linux-melb:xfs-kern:26984a Signed-off-by: Vlad Apostolov Signed-off-by: Tim Shimmin --- fs/xfs/xfs_itable.c | 24 ++++++++++++++---------- fs/xfs/xfs_itable.h | 5 +++++ 2 files changed, 19 insertions(+), 10 deletions(-) (limited to 'fs') diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 136c6b06f1c..80e5b96f502 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -39,6 +39,16 @@ #include "xfs_error.h" #include "xfs_btree.h" +int +xfs_internal_inum( + xfs_mount_t *mp, + xfs_ino_t ino) +{ + return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || + (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && + (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))); +} + STATIC int xfs_bulkstat_one_iget( xfs_mount_t *mp, /* mount point for filesystem */ @@ -213,17 +223,12 @@ xfs_bulkstat_one( xfs_dinode_t *dip; /* dinode inode pointer */ dip = (xfs_dinode_t *)dibuff; + *stat = BULKSTAT_RV_NOTHING; - if (!buffer || ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || - (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) && - (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))) { - *stat = BULKSTAT_RV_NOTHING; + if (!buffer || xfs_internal_inum(mp, ino)) return XFS_ERROR(EINVAL); - } - if (ubsize < sizeof(*buf)) { - *stat = BULKSTAT_RV_NOTHING; + if (ubsize < sizeof(*buf)) return XFS_ERROR(ENOMEM); - } buf = kmem_alloc(sizeof(*buf), KM_SLEEP); @@ -239,8 +244,7 @@ xfs_bulkstat_one( } if (copy_to_user(buffer, buf, sizeof(*buf))) { - *stat = BULKSTAT_RV_NOTHING; - error = EFAULT; + error = EFAULT; goto out_free; } diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h index 6926c373a0a..f25a28862a1 100644 --- a/fs/xfs/xfs_itable.h +++ b/fs/xfs/xfs_itable.h @@ -81,6 +81,11 @@ xfs_bulkstat_one( void *dibuff, int *stat); +int +xfs_internal_inum( + xfs_mount_t *mp, + xfs_ino_t ino); + int /* error status */ xfs_inumbers( xfs_mount_t *mp, /* mount point for filesystem */ -- cgit v1.2.3 From 6e73b418887675da18602550ca296211caeb3897 Mon Sep 17 00:00:00 2001 From: Vlad Apostolov Date: Thu, 28 Sep 2006 11:06:21 +1000 Subject: [XFS] 955947: Infinite loop in xfs_bulkstat() on formatter() error SGI-PV: 955947 SGI-Modid: xfs-linux-melb:xfs-kern:26986a Signed-off-by: Vlad Apostolov Signed-off-by: Tim Shimmin --- fs/xfs/xfs_itable.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs') diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 80e5b96f502..7775ddc0b3c 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -647,6 +647,8 @@ xfs_bulkstat( } else if (error == ENOMEM) ubleft = 0; + else + lastino = ino; continue; } if (fmterror == BULKSTAT_RV_GIVEUP) { -- cgit v1.2.3 From 65e8697a12e356cd7a6ecafa1149f5c5c6a71593 Mon Sep 17 00:00:00 2001 From: Tim Shimmin Date: Fri, 29 Sep 2006 15:23:02 +1000 Subject: [XFS] Remove v1 dir trace macro - missed in a past commit. Signed-off-by: Tim Shimmin --- fs/xfs/Makefile-linux-2.6 | 1 - 1 file changed, 1 deletion(-) (limited to 'fs') diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 index 9e7f85986d0..291948d5085 100644 --- a/fs/xfs/Makefile-linux-2.6 +++ b/fs/xfs/Makefile-linux-2.6 @@ -30,7 +30,6 @@ ifeq ($(CONFIG_XFS_TRACE),y) EXTRA_CFLAGS += -DXFS_BLI_TRACE EXTRA_CFLAGS += -DXFS_BMAP_TRACE EXTRA_CFLAGS += -DXFS_BMBT_TRACE - EXTRA_CFLAGS += -DXFS_DIR_TRACE EXTRA_CFLAGS += -DXFS_DIR2_TRACE EXTRA_CFLAGS += -DXFS_DQUOT_TRACE EXTRA_CFLAGS += -DXFS_ILOCK_TRACE -- cgit v1.2.3 From f71b2f10f56802075d67c5710cd9f1816382d720 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Fri, 29 Sep 2006 01:58:39 -0700 Subject: [PATCH] JBD: Make journal_brelse_array() static It's always good to make symbols static when we can, and this also eliminates the need to rename the function in jbd2 Suggested by Eric Sandeen. Signed-off-by: Dave Kleikamp Cc: Eric Sandeen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/jbd/recovery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c index 445eed6ce5d..11563fe2a52 100644 --- a/fs/jbd/recovery.c +++ b/fs/jbd/recovery.c @@ -46,7 +46,7 @@ static int scan_revoke_records(journal_t *, struct buffer_head *, #ifdef __KERNEL__ /* Release readahead buffers after use */ -void journal_brelse_array(struct buffer_head *b[], int n) +static void journal_brelse_array(struct buffer_head *b[], int n) { while (--n >= 0) brelse (b[n]); -- cgit v1.2.3 From d1807793e1e7e502e3dc047115e9dbc3b50e4534 Mon Sep 17 00:00:00 2001 From: Zoltan Menyhart Date: Fri, 29 Sep 2006 01:58:40 -0700 Subject: [PATCH] JBD: memory leak in "journal_init_dev()" We leak a bh ref in "journal_init_dev()" in case of failure. Signed-off-by: Zoltan Menyhart Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/jbd/journal.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'fs') diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 2fc66c3e668..7af6099c911 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -715,18 +715,8 @@ journal_t * journal_init_dev(struct block_device *bdev, if (!journal) return NULL; - journal->j_dev = bdev; - journal->j_fs_dev = fs_dev; - journal->j_blk_offset = start; - journal->j_maxlen = len; - journal->j_blocksize = blocksize; - - bh = __getblk(journal->j_dev, start, journal->j_blocksize); - J_ASSERT(bh != NULL); - journal->j_sb_buffer = bh; - journal->j_superblock = (journal_superblock_t *)bh->b_data; - /* journal descriptor can store up to n blocks -bzzz */ + journal->j_blocksize = blocksize; n = journal->j_blocksize / sizeof(journal_block_tag_t); journal->j_wbufsize = n; journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); @@ -736,6 +726,15 @@ journal_t * journal_init_dev(struct block_device *bdev, kfree(journal); journal = NULL; } + journal->j_dev = bdev; + journal->j_fs_dev = fs_dev; + journal->j_blk_offset = start; + journal->j_maxlen = len; + + bh = __getblk(journal->j_dev, start, journal->j_blocksize); + J_ASSERT(bh != NULL); + journal->j_sb_buffer = bh; + journal->j_superblock = (journal_superblock_t *)bh->b_data; return journal; } -- cgit v1.2.3 From 4d7dd8fd9557840162b724a8ac1366dd78a12dff Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 29 Sep 2006 01:58:56 -0700 Subject: [PATCH] blockdev.c: check driver layer errors Check driver layer errors. Fix from: "Jun'ichi Nomura" In blockdevc-check-errors.patch, add_bd_holder() is modified to return error values when some of its operation failed. Among them, it returns -EEXIST when a given bd_holder object already exists in the list. However, in this case, the function completed its work successfully and need no action by its caller other than freeing unused bd_holder object. So I think it's better to return success after freeing by itself. Otherwise, bd_claim-ing with same claim pointer will fail. Typically, lvresize will fails with following message: device-mapper: reload ioctl failed: Invalid argument and you'll see messages like below in kernel log: device-mapper: table: 254:13: linear: dm-linear: Device lookup failed device-mapper: ioctl: error adding target to table Similarly, it should not add bd_holder to the list if either one of symlinking fails. I don't have a test case for this to happen but it should cause dereference of freed pointer. If a matching bd_holder is found in bd_holder_list, add_bd_holder() completes its job by just incrementing the reference count. In this case, it should be considered as success but it used to return 'fail' to let the caller free temporary bd_holder. Fixed it to return success and free given object by itself. Also, if either one of symlinking fails, the bd_holder should not be added to the list so that it can be discarded later. Otherwise, the caller will free bd_holder which is in the list. Signed-off-by: Jun'ichi Nomura Cc: "Randy.Dunlap" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/block_dev.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'fs') diff --git a/fs/block_dev.c b/fs/block_dev.c index 045f98854f1..8cc144ffc38 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -543,11 +543,11 @@ static struct kobject *bdev_get_holder(struct block_device *bdev) return kobject_get(bdev->bd_disk->holder_dir); } -static void add_symlink(struct kobject *from, struct kobject *to) +static int add_symlink(struct kobject *from, struct kobject *to) { if (!from || !to) - return; - sysfs_create_link(from, to, kobject_name(to)); + return 0; + return sysfs_create_link(from, to, kobject_name(to)); } static void del_symlink(struct kobject *from, struct kobject *to) @@ -648,30 +648,38 @@ static void free_bd_holder(struct bd_holder *bo) * If there is no matching entry with @bo in @bdev->bd_holder_list, * add @bo to the list, create symlinks. * - * Returns 1 if @bo was added to the list. - * Returns 0 if @bo wasn't used by any reason and should be freed. + * Returns 0 if symlinks are created or already there. + * Returns -ve if something fails and @bo can be freed. */ static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) { struct bd_holder *tmp; + int ret; if (!bo) - return 0; + return -EINVAL; list_for_each_entry(tmp, &bdev->bd_holder_list, list) { if (tmp->sdir == bo->sdir) { tmp->count++; + /* We've already done what we need to do here. */ + free_bd_holder(bo); return 0; } } if (!bd_holder_grab_dirs(bdev, bo)) - return 0; + return -EBUSY; - add_symlink(bo->sdir, bo->sdev); - add_symlink(bo->hdir, bo->hdev); - list_add_tail(&bo->list, &bdev->bd_holder_list); - return 1; + ret = add_symlink(bo->sdir, bo->sdev); + if (ret == 0) { + ret = add_symlink(bo->hdir, bo->hdev); + if (ret) + del_symlink(bo->sdir, bo->sdev); + } + if (ret == 0) + list_add_tail(&bo->list, &bdev->bd_holder_list); + return ret; } /** @@ -741,7 +749,9 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); res = bd_claim(bdev, holder); - if (res || !add_bd_holder(bdev, bo)) + if (res == 0) + res = add_bd_holder(bdev, bo); + if (res) free_bd_holder(bo); mutex_unlock(&bdev->bd_mutex); -- cgit v1.2.3 From 15a67dd8ccf696392176c95a08234a8b8ee59005 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 29 Sep 2006 01:58:57 -0700 Subject: [PATCH] fs/namespace: handle init/registration errors Check and handle init errors. Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namespace.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/namespace.c b/fs/namespace.c index 36d18085813..6ede3a539ed 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -1813,6 +1814,7 @@ void __init mnt_init(unsigned long mempages) struct list_head *d; unsigned int nr_hash; int i; + int err; init_rwsem(&namespace_sem); @@ -1853,8 +1855,14 @@ void __init mnt_init(unsigned long mempages) d++; i--; } while (i); - sysfs_init(); - subsystem_register(&fs_subsys); + err = sysfs_init(); + if (err) + printk(KERN_WARNING "%s: sysfs_init error: %d\n", + __FUNCTION__, err); + err = subsystem_register(&fs_subsys); + if (err) + printk(KERN_WARNING "%s: subsystem_register error: %d\n", + __FUNCTION__, err); init_rootfs(); init_mount_tree(); } -- cgit v1.2.3 From c0d92cbc5849f26451f478d538b8d885ae547221 Mon Sep 17 00:00:00 2001 From: Pekka J Enberg Date: Fri, 29 Sep 2006 01:59:09 -0700 Subject: [PATCH] libfs: remove page up-to-date check from simple_readpage Remove the unnecessary PageUptodate check from simple_readpage. The only two callers for ->readpage that don't have explicit PageUptodate check are read_cache_pages and page_cache_read which operate on newly allocated pages which don't have the flag set. [akpm: use the allegedly-faster clear_page(), too] Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/libfs.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'fs') diff --git a/fs/libfs.c b/fs/libfs.c index 8db5afb7b0a..3793aaa1457 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -317,17 +317,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, int simple_readpage(struct file *file, struct page *page) { - void *kaddr; - - if (PageUptodate(page)) - goto out; - - kaddr = kmap_atomic(page, KM_USER0); - memset(kaddr, 0, PAGE_CACHE_SIZE); - kunmap_atomic(kaddr, KM_USER0); + clear_highpage(page); flush_dcache_page(page); SetPageUptodate(page); -out: unlock_page(page); return 0; } -- cgit v1.2.3 From 42012cc4a2183c555a907eee32d7ce4fc7dc3a6a Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 29 Sep 2006 01:59:21 -0700 Subject: [PATCH] use gcc -O1 in fs/reiserfs only for ancient gcc versions Only compile with -O1 if the (very old) compiler is broken. We use reiserfs alot since SLES9 on ppc64, and it was never seen with gcc33. Assume the broken gcc is gcc-3.4 or older. Signed-off-by: Olaf Hering Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/reiserfs/Makefile b/fs/reiserfs/Makefile index 3a59309f3ca..0eb7ac08048 100644 --- a/fs/reiserfs/Makefile +++ b/fs/reiserfs/Makefile @@ -28,7 +28,7 @@ endif # will work around it. If any other architecture displays this behavior, # add it here. ifeq ($(CONFIG_PPC32),y) -EXTRA_CFLAGS := -O1 +EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0400, -O1) endif TAGS: -- cgit v1.2.3 From 58f555e5f62b6a8326caf6d45ac611186f24587d Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 29 Sep 2006 01:59:24 -0700 Subject: [PATCH] mbcache: add lock annotation for __mb_cache_entry_release_unlock() __mb_cache_entry_release_unlock releases mb_cache_spinlock, so annotate it accordingly. Signed-off-by: Josh Triplett Cc: Andreas Gruenbacher Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/mbcache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/mbcache.c b/fs/mbcache.c index e4fde1ab22c..0ff71256e65 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -160,6 +160,7 @@ __mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask) static void __mb_cache_entry_release_unlock(struct mb_cache_entry *ce) + __releases(mb_cache_spinlock) { /* Wake up all processes queuing for this cache entry. */ if (ce->e_queued) -- cgit v1.2.3 From 99fc705996285ed2746c0c8ae8313d0a04d62ec9 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 29 Sep 2006 01:59:25 -0700 Subject: [PATCH] afs: add lock annotations to afs_proc_cell_servers_{start,stop} afs_proc_cell_servers_start acquires a lock, and afs_proc_cell_servers_stop releases that lock. Add lock annotations to these two functions so that sparse can check callers for lock pairing, and so that sparse will not complain about these functions since they intentionally use locks in this manner. Signed-off-by: Josh Triplett Acked-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/afs/proc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs') diff --git a/fs/afs/proc.c b/fs/afs/proc.c index 101d21b6c03..86463ec9ccb 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c @@ -775,6 +775,7 @@ static int afs_proc_cell_servers_release(struct inode *inode, * first item */ static void *afs_proc_cell_servers_start(struct seq_file *m, loff_t *_pos) + __acquires(m->private->sv_lock) { struct list_head *_p; struct afs_cell *cell = m->private; @@ -823,6 +824,7 @@ static void *afs_proc_cell_servers_next(struct seq_file *p, void *v, * clean up after reading from the cells list */ static void afs_proc_cell_servers_stop(struct seq_file *p, void *v) + __releases(p->private->sv_lock) { struct afs_cell *cell = p->private; -- cgit v1.2.3 From 105f4d7a813e9ef6be58549f5d2a49af1764da19 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 29 Sep 2006 01:59:25 -0700 Subject: [PATCH] fuse: add lock annotations to request_end and fuse_read_interrupt request_end and fuse_read_interrupt release fc->lock. Add lock annotations to these two functions so that sparse can check callers for lock pairing, and so that sparse will not complain about these functions since they intentionally use locks in this manner. Signed-off-by: Josh Triplett Acked-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fuse/dev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'fs') diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 1e2006caf15..4fc557c40cc 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -212,6 +212,7 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) * Called with fc->lock, unlocks it */ static void request_end(struct fuse_conn *fc, struct fuse_req *req) + __releases(fc->lock) { void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; req->end = NULL; @@ -640,6 +641,7 @@ static void request_wait(struct fuse_conn *fc) */ static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, const struct iovec *iov, unsigned long nr_segs) + __releases(fc->lock) { struct fuse_copy_state cs; struct fuse_in_header ih; -- cgit v1.2.3 From ddc0a51d2e351985aa542ff650635e2fd62d3f8b Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 29 Sep 2006 01:59:27 -0700 Subject: [PATCH] hugetlbfs: add lock annotation to hugetlbfs_forget_inode() hugetlbfs_forget_inode releases inode_lock. Add a lock annotation to this function so that sparse can check callers for lock pairing, and so that sparse will not complain about this functions since it intentionally uses the lock in this manner. Signed-off-by: Josh Triplett Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/hugetlbfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index e025a31b4c6..f5b8f329aca 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -229,7 +229,7 @@ static void hugetlbfs_delete_inode(struct inode *inode) clear_inode(inode); } -static void hugetlbfs_forget_inode(struct inode *inode) +static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock) { struct super_block *sb = inode->i_sb; -- cgit v1.2.3 From 9c4dbee79d3f46608bec3ac80d392ce6415d2f90 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 29 Sep 2006 01:59:29 -0700 Subject: [PATCH] fs: add lock annotation to grab_super grab_super gets called with sb_lock held, and releases it. Add a lock annotation to this function so that sparse can check callers for lock pairing, and so that sparse will not complain about this function since it intentionally uses the lock in this manner. Signed-off-by: Josh Triplett Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/super.c b/fs/super.c index 5c4c94d5495..6987824d0dc 100644 --- a/fs/super.c +++ b/fs/super.c @@ -199,7 +199,7 @@ EXPORT_SYMBOL(deactivate_super); * success, 0 if we had failed (superblock contents was already dead or * dying when grab_super() had been called). */ -static int grab_super(struct super_block *s) +static int grab_super(struct super_block *s) __releases(sb_lock) { s->s_count++; spin_unlock(&sb_lock); -- cgit v1.2.3 From 8454aeef6fea944ced757ff8e761b59eb3ee960f Mon Sep 17 00:00:00 2001 From: Eugene Teo Date: Fri, 29 Sep 2006 01:59:33 -0700 Subject: [PATCH] Require mmap handler for a.out executables Files supported by fs/proc/base.c, i.e. /proc//*, are not capable of meeting the validity checks in ELF load_elf_*() handling because they have no mmap handler which is required by ELF. In order to stop a.out executables being used as part of an exploit attack against /proc-related vulnerabilities, we make a.out executables depend on ->mmap() existing. Signed-off-by: Eugene Teo Signed-off-by: Marcel Holtmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_aout.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'fs') diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index f312103434d..517e111bb7e 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c @@ -278,6 +278,13 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) return -ENOEXEC; } + /* + * Requires a mmap handler. This prevents people from using a.out + * as part of an exploit attack against /proc-related vulnerabilities. + */ + if (!bprm->file->f_op || !bprm->file->f_op->mmap) + return -ENOEXEC; + fd_offset = N_TXTOFF(ex); /* Check initial limits. This avoids letting people circumvent @@ -476,6 +483,13 @@ static int load_aout_library(struct file *file) goto out; } + /* + * Requires a mmap handler. This prevents people from using a.out + * as part of an exploit attack against /proc-related vulnerabilities. + */ + if (!file->f_op || !file->f_op->mmap) + goto out; + if (N_FLAGS(ex)) goto out; -- cgit v1.2.3 From 5b35e8e58a315b16d123e2bc080fcc9981501ac4 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 29 Sep 2006 01:59:34 -0700 Subject: [PATCH] fuse: use dentry in statfs Some filesystems may want to report different values depending on the path within the filesystem, i.e. one mount is actually several filesystems. This can be the case for a network filesystem exported by an unprivileged server (e.g. sshfs). This is now possible, thanks to David Howells "VFS: Permit filesystem to perform statfs with a known root dentry" patch. This change is backward compatible, so no need to change interface version. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fuse/inode.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index cb7cadb0b79..7d0a9aee01f 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -251,6 +251,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) memset(&outarg, 0, sizeof(outarg)); req->in.numargs = 0; req->in.h.opcode = FUSE_STATFS; + req->in.h.nodeid = get_node_id(dentry->d_inode); req->out.numargs = 1; req->out.args[0].size = fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); -- cgit v1.2.3 From 650a898342b3fa21c392c06a2b7010fa19823efa Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 29 Sep 2006 01:59:35 -0700 Subject: [PATCH] vfs: define new lookup flag for chdir In the "operation does permission checking" model used by fuse, chdir permission is not checked, since there's no chdir method. For this case set a lookup flag, which will be passed to ->permission(), so fuse can distinguish it from permission checks for other operations. Signed-off-by: Miklos Szeredi Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fuse/dir.c | 2 +- fs/open.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 409ce6a7cca..f85b2a282f1 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -776,7 +776,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO)) return -EACCES; - if (nd && (nd->flags & LOOKUP_ACCESS)) + if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) return fuse_access(inode, mask); return 0; } diff --git a/fs/open.c b/fs/open.c index 303f06d2a7b..1574d8fe490 100644 --- a/fs/open.c +++ b/fs/open.c @@ -546,7 +546,8 @@ asmlinkage long sys_chdir(const char __user * filename) struct nameidata nd; int error; - error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd); + error = __user_walk(filename, + LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd); if (error) goto out; -- cgit v1.2.3 From e1dfa92dcab72397ed1f85f7b8f98a9da43b3f7b Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 29 Sep 2006 01:59:39 -0700 Subject: [PATCH] ignore partition table on disks with AIX label The on-disk data structures from AIX are not known, also the filesystem layout is not known. There is a msdos partition signature at the end of the first block, and the kernel recognizes 3 small (and overlapping) partitions. But they are not usable. Maybe the firmware uses it to find the bootloader for AIX, but AIX boots also if the first block is cleared. This is the content of the partition table: # dd if=/dev/sdb count=$(( 4 * 16 )) bs=1 skip=$(( 0x1be )) | xxd 0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000010: 80ff ffff 41ff ffff 1b11 0000 381b 0000 ....A.......8... 0000020: 00ff ffff 41ff ffff 0211 0000 1900 0000 ....A........... 0000030: 80ff ffff 41ff ffff 1b11 0000 381b 0000 ....A.......8... Handle the whole disk as empty disk. This fixes also YaST which compares the output from parted (and formerly fdisk) with /proc/partitions. fdisk recognizes the AIX label since a long time, SuSE has a patch for parted to handle the disk label as unknown. dmesg will look like this: sda: [AIX] unknown partition table Tested on an IBM B50 with AIX V4.3.3. Signed-off-by: Olaf Hering Cc: Albert Cahalan Cc: OGAWA Hirofumi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/partitions/msdos.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'fs') diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 8f12587c312..4f8df71e49d 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c @@ -58,6 +58,31 @@ msdos_magic_present(unsigned char *p) return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2); } +/* Value is EBCDIC 'IBMA' */ +#define AIX_LABEL_MAGIC1 0xC9 +#define AIX_LABEL_MAGIC2 0xC2 +#define AIX_LABEL_MAGIC3 0xD4 +#define AIX_LABEL_MAGIC4 0xC1 +static int aix_magic_present(unsigned char *p, struct block_device *bdev) +{ + Sector sect; + unsigned char *d; + int ret = 0; + + if (p[0] != AIX_LABEL_MAGIC1 && + p[1] != AIX_LABEL_MAGIC2 && + p[2] != AIX_LABEL_MAGIC3 && + p[3] != AIX_LABEL_MAGIC4) + return 0; + d = read_dev_sector(bdev, 7, §); + if (d) { + if (d[0] == '_' && d[1] == 'L' && d[2] == 'V' && d[3] == 'M') + ret = 1; + put_dev_sector(sect); + }; + return ret; +} + /* * Create devices for each logical partition in an extended partition. * The logical partitions form a linked list, with each entry being @@ -393,6 +418,12 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) return 0; } + if (aix_magic_present(data, bdev)) { + put_dev_sector(sect); + printk( " [AIX]"); + return 0; + } + /* * Now that the 55aa signature is present, this is probably * either the boot sector of a FAT filesystem or a DOS-type -- cgit v1.2.3 From 39b3f6d6e915aa29ad6f90d1517d9217f903c8dc Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Fri, 29 Sep 2006 01:59:41 -0700 Subject: [PATCH] mount udf UDF_PART_FLAG_READ_ONLY partitions with MS_RDONLY There's a bug where a UDF_PART_FLAG_READ_ONLY udf partition gets mounted read-write, then subsequent problems happen; files seem to be able to be removed, but file creation results in EIO or worse, oops. EIO is coming from udf_new_block(), which returns EIO if the right flags aren't set; only UDF_PART_FLAG_READ_ONLY is set in this case. We probably s hould not have gotten this far... Attached patch seems to fix it - and includes a printk to alert the user that their "rw" mount request has been converted to "ro." Here's the testcase I used: [root@magnesium ~]# mkisofs -R -J -udf -o testiso /tmp/ ... Total translation table size: 0 Total rockridge attributes bytes: 342923 Total directory bytes: 382312 Path table size(bytes): 104 Max brk space used 103000 105059 extents written (205 MB) [root@magnesium ~]# mount -o loop testiso /mnt/test/ [root@magnesium ~]# ls /mnt/test/fsfile /mnt/test/fsfile [root@magnesium ~]# rm /mnt/test/fsfile [root@magnesium ~]# ls /mnt/test/fsfile ls: /mnt/test/fsfile: No such file or directory [root@magnesium ~]# touch /mnt/test/fsfile touch: cannot touch `/mnt/test/fsfile': Input/output error [root@magnesium tmp]# grep udf /proc/mounts /dev/loop1 /mnt/test udf rw 0 0 Force readonly mounts of UDF partitions marked as read-only. Signed-off-by: Eric Sandeen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/udf/super.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs') diff --git a/fs/udf/super.c b/fs/udf/super.c index 5dd356cbbda..1d3b5d2070e 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1621,6 +1621,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) goto error_out; } + if (UDF_SB_PARTFLAGS(sb, UDF_SB_PARTITION(sb)) & UDF_PART_FLAG_READ_ONLY) + printk("UDF-fs: Partition marked readonly; forcing readonly mount\n"); + sb->s_flags |= MS_RDONLY; + if ( udf_find_fileset(sb, &fileset, &rootdir) ) { printk("UDF-fs: No fileset found\n"); -- cgit v1.2.3 From 25736b1c692d436508585d1d710912e6f76be2d8 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 29 Sep 2006 01:59:54 -0700 Subject: [PATCH] reiserfs_fsync should only use barriers when they are enabled make sure that reiserfs_fsync only triggers barriers when mounted with -o barrier=flush Signed-off-by: Chris Mason Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 1627edd5081..1cfbe857ba2 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -130,7 +130,7 @@ static int reiserfs_sync_file(struct file *p_s_filp, reiserfs_write_lock(p_s_inode->i_sb); barrier_done = reiserfs_commit_for_inode(p_s_inode); reiserfs_write_unlock(p_s_inode->i_sb); - if (barrier_done != 1) + if (barrier_done != 1 && reiserfs_barrier_flush(p_s_inode->i_sb)) blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL); if (barrier_done < 0) return barrier_done; -- cgit v1.2.3 From a3172027148120b8f8797cbecc7d0a0b215736a1 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 29 Sep 2006 01:59:56 -0700 Subject: [PATCH] Fix reiserfs latencies caused by data=ordered ReiserFS does periodic cleanup of old transactions in order to limit the length of time a journal replay may take after a crash. Sometimes, writing metadata from an old (already committed) transaction may require committing a newer transaction, which also requires writing all data=ordered buffers. This can cause very long stalls on journal_begin. This patch makes sure new transactions will not need to be committed before trying a periodic reclaim of an old transaction. It is low risk because if a bad decision is made, it just means a slightly longer journal replay after a crash. Signed-off-by: Chris Mason Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/journal.c | 54 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 11 deletions(-) (limited to 'fs') diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 9b3672d6936..e6b5ccf23f1 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -1186,6 +1186,21 @@ static struct reiserfs_journal_list *find_newer_jl_for_cn(struct return NULL; } +static int newer_jl_done(struct reiserfs_journal_cnode *cn) +{ + struct super_block *sb = cn->sb; + b_blocknr_t blocknr = cn->blocknr; + + cn = cn->hprev; + while (cn) { + if (cn->sb == sb && cn->blocknr == blocknr && cn->jlist && + atomic_read(&cn->jlist->j_commit_left) != 0) + return 0; + cn = cn->hprev; + } + return 1; +} + static void remove_journal_hash(struct super_block *, struct reiserfs_journal_cnode **, struct reiserfs_journal_list *, unsigned long, @@ -1604,6 +1619,31 @@ static int flush_journal_list(struct super_block *s, return err; } +static int test_transaction(struct super_block *s, + struct reiserfs_journal_list *jl) +{ + struct reiserfs_journal_cnode *cn; + + if (jl->j_len == 0 || atomic_read(&jl->j_nonzerolen) == 0) + return 1; + + cn = jl->j_realblock; + while (cn) { + /* if the blocknr == 0, this has been cleared from the hash, + ** skip it + */ + if (cn->blocknr == 0) { + goto next; + } + if (cn->bh && !newer_jl_done(cn)) + return 0; + next: + cn = cn->next; + cond_resched(); + } + return 0; +} + static int write_one_transaction(struct super_block *s, struct reiserfs_journal_list *jl, struct buffer_chunk *chunk) @@ -3433,16 +3473,6 @@ static void flush_async_commits(void *p) flush_commit_list(p_s_sb, jl, 1); } unlock_kernel(); - /* - * this is a little racey, but there's no harm in missing - * the filemap_fdata_write - */ - if (!atomic_read(&journal->j_async_throttle) - && !reiserfs_is_journal_aborted(journal)) { - atomic_inc(&journal->j_async_throttle); - filemap_fdatawrite(p_s_sb->s_bdev->bd_inode->i_mapping); - atomic_dec(&journal->j_async_throttle); - } } /* @@ -3844,7 +3874,9 @@ static void flush_old_journal_lists(struct super_block *s) entry = journal->j_journal_list.next; jl = JOURNAL_LIST_ENTRY(entry); /* this check should always be run, to send old lists to disk */ - if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4))) { + if (jl->j_timestamp < (now - (JOURNAL_MAX_TRANS_AGE * 4)) && + atomic_read(&jl->j_commit_left) == 0 && + test_transaction(s, jl)) { flush_used_journal_lists(s, jl); } else { break; -- cgit v1.2.3 From 068fbb315dd1e9dd3418aac39a9cfeabe39c16a6 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 29 Sep 2006 01:59:58 -0700 Subject: [PATCH] reiserfs: ifdef xattr_sem Shrink reiserfs inode by 12 bytes for xattr non-users (me). -reiser_inode_cache 356 11 +reiser_inode_cache 344 11 Signed-off-by: Alexey Dobriyan Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 8810fda0da4..78f23f40693 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1129,7 +1129,7 @@ static void init_inode(struct inode *inode, struct path *path) REISERFS_I(inode)->i_jl = NULL; REISERFS_I(inode)->i_acl_access = NULL; REISERFS_I(inode)->i_acl_default = NULL; - init_rwsem(&REISERFS_I(inode)->xattr_sem); + reiserfs_init_xattr_rwsem(inode); if (stat_data_v1(ih)) { struct stat_data_v1 *sd = @@ -1836,7 +1836,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); REISERFS_I(inode)->i_acl_access = NULL; REISERFS_I(inode)->i_acl_default = NULL; - init_rwsem(&REISERFS_I(inode)->xattr_sem); + reiserfs_init_xattr_rwsem(inode); if (old_format_only(sb)) make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET, -- cgit v1.2.3 From cfe14677f286c9be5d683b88214def8f4b8a6f24 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 29 Sep 2006 02:00:00 -0700 Subject: [PATCH] reiserfs: ifdef ACL stuff from inode Shrink reiserfs inode more (by 8 bytes) for ACL non-users: -reiser_inode_cache 344 11 +reiser_inode_cache 336 11 Signed-off-by: Alexey Dobriyan Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/inode.c | 10 ++++++---- fs/reiserfs/super.c | 6 ++++++ 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 78f23f40693..7e5a2f5ebeb 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1127,8 +1127,8 @@ static void init_inode(struct inode *inode, struct path *path) REISERFS_I(inode)->i_prealloc_count = 0; REISERFS_I(inode)->i_trans_id = 0; REISERFS_I(inode)->i_jl = NULL; - REISERFS_I(inode)->i_acl_access = NULL; - REISERFS_I(inode)->i_acl_default = NULL; + reiserfs_init_acl_access(inode); + reiserfs_init_acl_default(inode); reiserfs_init_xattr_rwsem(inode); if (stat_data_v1(ih)) { @@ -1834,8 +1834,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, REISERFS_I(inode)->i_attrs = REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); - REISERFS_I(inode)->i_acl_access = NULL; - REISERFS_I(inode)->i_acl_default = NULL; + reiserfs_init_acl_access(inode); + reiserfs_init_acl_default(inode); reiserfs_init_xattr_rwsem(inode); if (old_format_only(sb)) @@ -1974,11 +1974,13 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, * iput doesn't deadlock in reiserfs_delete_xattrs. The locking * code really needs to be reworked, but this will take care of it * for now. -jeffm */ +#ifdef CONFIG_REISERFS_FS_POSIX_ACL if (REISERFS_I(dir)->i_acl_default && !IS_ERR(REISERFS_I(dir)->i_acl_default)) { reiserfs_write_unlock_xattrs(dir->i_sb); iput(inode); reiserfs_write_lock_xattrs(dir->i_sb); } else +#endif iput(inode); return err; } diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b40d4d64d59..80fc3b32802 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -510,8 +510,10 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) SLAB_CTOR_CONSTRUCTOR) { INIT_LIST_HEAD(&ei->i_prealloc_list); inode_init_once(&ei->vfs_inode); +#ifdef CONFIG_REISERFS_FS_POSIX_ACL ei->i_acl_access = NULL; ei->i_acl_default = NULL; +#endif } } @@ -560,6 +562,7 @@ static void reiserfs_dirty_inode(struct inode *inode) reiserfs_write_unlock(inode->i_sb); } +#ifdef CONFIG_REISERFS_FS_POSIX_ACL static void reiserfs_clear_inode(struct inode *inode) { struct posix_acl *acl; @@ -574,6 +577,9 @@ static void reiserfs_clear_inode(struct inode *inode) posix_acl_release(acl); REISERFS_I(inode)->i_acl_default = NULL; } +#else +#define reiserfs_clear_inode NULL +#endif #ifdef CONFIG_QUOTA static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, -- cgit v1.2.3 From 50462062a02226a698a211d5bd535376c89b8603 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 29 Sep 2006 02:00:01 -0700 Subject: [PATCH] fs.h: ifdef security fields [assuming BSD security levels are deleted] The only user of i_security, f_security, s_security fields is SELinux, however, quite a few security modules are trying to get into kernel. So, wrap them under CONFIG_SECURITY. Adding config option for each security field is likely an overkill. Following Stephen Smalley's suggestion, i_security initialization is moved to security_inode_alloc() to not clutter core code with ifdefs and make alloc_inode() codepath tiny little bit smaller and faster. The user of (highly greppable) struct fown_struct::security field is still to be found. I've checked every "fown_struct" and every "f_owner" occurence. Additionally it's removal doesn't break i386 allmodconfig build. struct inode, struct file, struct super_block, struct fown_struct become smaller. P.S. Combined with two reiserfs inode shrinking patches sent to linux-fsdevel, I can finally suck 12 reiserfs inodes into one page. /proc/slabinfo -ext2_inode_cache 388 10 +ext2_inode_cache 384 10 -inode_cache 280 14 +inode_cache 276 14 -proc_inode_cache 296 13 +proc_inode_cache 292 13 -reiser_inode_cache 336 11 +reiser_inode_cache 332 12 <= -shmem_inode_cache 372 10 +shmem_inode_cache 368 10 Signed-off-by: Alexey Dobriyan Cc: Stephen Smalley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/inode.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs') diff --git a/fs/inode.c b/fs/inode.c index f5c04dd9ae8..abf77471e6c 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -133,7 +133,6 @@ static struct inode *alloc_inode(struct super_block *sb) inode->i_bdev = NULL; inode->i_cdev = NULL; inode->i_rdev = 0; - inode->i_security = NULL; inode->dirtied_when = 0; if (security_inode_alloc(inode)) { if (inode->i_sb->s_op->destroy_inode) -- cgit v1.2.3 From ae78bf9c4f5fde3c67e2829505f195d7347ce3e4 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 29 Sep 2006 02:00:03 -0700 Subject: [PATCH] add -o flush for fat Fat is commonly used on removable media. Mounting with -o flush tells the FS to write things to disk as quickly as possible. It is like -o sync, but much faster (and not as safe). Signed-off-by: Chris Mason Cc: OGAWA Hirofumi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fat/file.c | 13 +++++++++++++ fs/fat/inode.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- fs/msdos/namei.c | 11 ++++++++++- 3 files changed, 80 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/fat/file.c b/fs/fat/file.c index 1ee25232e6a..d50fc47169c 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -13,6 +13,7 @@ #include #include #include +#include int fat_generic_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) @@ -112,6 +113,16 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp, } } +static int fat_file_release(struct inode *inode, struct file *filp) +{ + if ((filp->f_mode & FMODE_WRITE) && + MSDOS_SB(inode->i_sb)->options.flush) { + fat_flush_inodes(inode->i_sb, inode, NULL); + blk_congestion_wait(WRITE, HZ/10); + } + return 0; +} + const struct file_operations fat_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, @@ -121,6 +132,7 @@ const struct file_operations fat_file_operations = { .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, + .release = fat_file_release, .ioctl = fat_generic_ioctl, .fsync = file_fsync, .sendfile = generic_file_sendfile, @@ -289,6 +301,7 @@ void fat_truncate(struct inode *inode) lock_kernel(); fat_free(inode, nr_clusters); unlock_kernel(); + fat_flush_inodes(inode->i_sb, inode, NULL); } struct inode_operations fat_file_inode_operations = { diff --git a/fs/fat/inode.c b/fs/fat/inode.c index ab96ae82375..045738032a8 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #ifndef CONFIG_FAT_DEFAULT_IOCHARSET @@ -853,7 +854,7 @@ enum { Opt_charset, Opt_shortname_lower, Opt_shortname_win95, Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes, Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes, - Opt_obsolate, Opt_err, + Opt_obsolate, Opt_flush, Opt_err, }; static match_table_t fat_tokens = { @@ -885,7 +886,8 @@ static match_table_t fat_tokens = { {Opt_obsolate, "cvf_format=%20s"}, {Opt_obsolate, "cvf_options=%100s"}, {Opt_obsolate, "posix"}, - {Opt_err, NULL} + {Opt_flush, "flush"}, + {Opt_err, NULL}, }; static match_table_t msdos_tokens = { {Opt_nodots, "nodots"}, @@ -1026,6 +1028,9 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, return 0; opts->codepage = option; break; + case Opt_flush: + opts->flush = 1; + break; /* msdos specific */ case Opt_dots: @@ -1425,6 +1430,56 @@ out_fail: EXPORT_SYMBOL_GPL(fat_fill_super); +/* + * helper function for fat_flush_inodes. This writes both the inode + * and the file data blocks, waiting for in flight data blocks before + * the start of the call. It does not wait for any io started + * during the call + */ +static int writeback_inode(struct inode *inode) +{ + + int ret; + struct address_space *mapping = inode->i_mapping; + struct writeback_control wbc = { + .sync_mode = WB_SYNC_NONE, + .nr_to_write = 0, + }; + /* if we used WB_SYNC_ALL, sync_inode waits for the io for the + * inode to finish. So WB_SYNC_NONE is sent down to sync_inode + * and filemap_fdatawrite is used for the data blocks + */ + ret = sync_inode(inode, &wbc); + if (!ret) + ret = filemap_fdatawrite(mapping); + return ret; +} + +/* + * write data and metadata corresponding to i1 and i2. The io is + * started but we do not wait for any of it to finish. + * + * filemap_flush is used for the block device, so if there is a dirty + * page for a block already in flight, we will not wait and start the + * io over again + */ +int fat_flush_inodes(struct super_block *sb, struct inode *i1, struct inode *i2) +{ + int ret = 0; + if (!MSDOS_SB(sb)->options.flush) + return 0; + if (i1) + ret = writeback_inode(i1); + if (!ret && i2) + ret = writeback_inode(i2); + if (!ret && sb) { + struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; + ret = filemap_flush(mapping); + } + return ret; +} +EXPORT_SYMBOL_GPL(fat_flush_inodes); + static int __init init_fat_fs(void) { int err; diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index 9e44158a754..d220165d491 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -280,7 +280,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { struct super_block *sb = dir->i_sb; - struct inode *inode; + struct inode *inode = NULL; struct fat_slot_info sinfo; struct timespec ts; unsigned char msdos_name[MSDOS_NAME]; @@ -316,6 +316,8 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, int mode, d_instantiate(dentry, inode); out: unlock_kernel(); + if (!err) + err = fat_flush_inodes(sb, dir, inode); return err; } @@ -348,6 +350,8 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) fat_detach(inode); out: unlock_kernel(); + if (!err) + err = fat_flush_inodes(inode->i_sb, dir, inode); return err; } @@ -401,6 +405,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode) d_instantiate(dentry, inode); unlock_kernel(); + fat_flush_inodes(sb, dir, inode); return 0; out_free: @@ -430,6 +435,8 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry) fat_detach(inode); out: unlock_kernel(); + if (!err) + err = fat_flush_inodes(inode->i_sb, dir, inode); return err; } @@ -635,6 +642,8 @@ static int msdos_rename(struct inode *old_dir, struct dentry *old_dentry, new_dir, new_msdos_name, new_dentry, is_hid); out: unlock_kernel(); + if (!err) + err = fat_flush_inodes(old_dir->i_sb, old_dir, new_dir); return err; } -- cgit v1.2.3 From 3b9b8ab65d8eed784b9164d03807cb2bda7b5cd6 Mon Sep 17 00:00:00 2001 From: Kirill Korotaev Date: Fri, 29 Sep 2006 02:00:05 -0700 Subject: [PATCH] Fix unserialized task->files changing Fixed race on put_files_struct on exec with proc. Restoring files on current on error path may lead to proc having a pointer to already kfree-d files_struct. ->files changing at exit.c and khtread.c are safe as exit_files() makes all things under lock. Found during OpenVZ stress testing. [akpm@osdl.org: add export] Signed-off-by: Pavel Emelianov Signed-off-by: Kirill Korotaev Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_elf.c | 6 ++---- fs/binfmt_misc.c | 6 ++---- fs/exec.c | 3 +-- 3 files changed, 5 insertions(+), 10 deletions(-) (limited to 'fs') diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index dfd8cfb7fb5..bb43da5cde5 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1038,10 +1038,8 @@ out_free_interp: out_free_file: sys_close(elf_exec_fileno); out_free_fh: - if (files) { - put_files_struct(current->files); - current->files = files; - } + if (files) + reset_files_struct(current, files); out_free_ph: kfree(elf_phdata); goto out; diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 66ba137f866..1713c48fef5 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -215,10 +215,8 @@ _error: bprm->interp_flags = 0; bprm->interp_data = 0; _unshare: - if (files) { - put_files_struct(current->files); - current->files = files; - } + if (files) + reset_files_struct(current, files); goto _ret; } diff --git a/fs/exec.c b/fs/exec.c index 97df6e0aeae..a8efe35176b 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -898,8 +898,7 @@ int flush_old_exec(struct linux_binprm * bprm) return 0; mmap_failed: - put_files_struct(current->files); - current->files = files; + reset_files_struct(current, files); out: return retval; } -- cgit v1.2.3 From 01d553d0fe9f90a132c5ff494872be8d4126be1e Mon Sep 17 00:00:00 2001 From: Amos Waterland Date: Fri, 29 Sep 2006 02:00:08 -0700 Subject: [PATCH] Chardev checking of overlapping ranges The code in __register_chrdev_region checks that if the driver wishing to register has the same major as an existing driver the new minor range is strictly less than the existing minor range. However, it does not also check that the new minor range is strictly greater than the existing minor range. That is, if driver X has registered with major=x and minor=0-3, __register_chrdev_region will allow driver Y to register with major=x and minor=1-4. Signed-off-by: Amos Waterland Cc: Linas Vepstas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/char_dev.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'fs') diff --git a/fs/char_dev.c b/fs/char_dev.c index 0009346d827..33b95af89da 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -128,13 +128,31 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) if ((*cp)->major > major || - ((*cp)->major == major && (*cp)->baseminor >= baseminor)) + ((*cp)->major == major && + (((*cp)->baseminor >= baseminor) || + ((*cp)->baseminor + (*cp)->minorct > baseminor)))) break; - if (*cp && (*cp)->major == major && - (*cp)->baseminor < baseminor + minorct) { - ret = -EBUSY; - goto out; + + /* Check for overlapping minor ranges. */ + if (*cp && (*cp)->major == major) { + int old_min = (*cp)->baseminor; + int old_max = (*cp)->baseminor + (*cp)->minorct - 1; + int new_min = baseminor; + int new_max = baseminor + minorct - 1; + + /* New driver overlaps from the left. */ + if (new_max >= old_min && new_max <= old_max) { + ret = -EBUSY; + goto out; + } + + /* New driver overlaps from the right. */ + if (new_min <= old_max && new_min >= old_min) { + ret = -EBUSY; + goto out; + } } + cd->next = *cp; *cp = cd; mutex_unlock(&chrdevs_lock); -- cgit v1.2.3 From ee731f4f7880b09ca147008ab46ad4e5f72cb8bf Mon Sep 17 00:00:00 2001 From: Ernie Petrides Date: Fri, 29 Sep 2006 02:00:13 -0700 Subject: [PATCH] fix wrong error code on interrupted close syscalls The problem is that close() syscalls can call a file system's flush handler, which in turn might sleep interruptibly and ultimately pass back an -ERESTARTSYS return value. This happens for files backed by an interruptible NFS mount under nfs_file_flush() when a large file has just been written and nfs_wait_bit_interruptible() detects that there is a signal pending. I have a test case where the "strace" command is used to attach to a process sleeping in such a close(). Since the SIGSTOP is forced onto the victim process (removing it from the thread's "blocked" mask in force_sig_info()), the RPC wait is interrupted and the close() is terminated early. But the file table entry has already been cleared before the flush handler was called. Thus, when the syscall is restarted, the file descriptor appears closed and an EBADF error is returned (which is wrong). What's worse, there is the hypothetical case where another thread of a multi-threaded application might have reused the file descriptor, in which case that file would be mistakenly closed. The bottom line is that close() syscalls are not restartable, and thus -ERESTARTSYS return values should be mapped to -EINTR. This is consistent with the close(2) manual page. The fix is below. Signed-off-by: Ernie Petrides Cc: Roland McGrath Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/open.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/open.c b/fs/open.c index 1574d8fe490..304c1c7814c 100644 --- a/fs/open.c +++ b/fs/open.c @@ -1173,6 +1173,7 @@ asmlinkage long sys_close(unsigned int fd) struct file * filp; struct files_struct *files = current->files; struct fdtable *fdt; + int retval; spin_lock(&files->file_lock); fdt = files_fdtable(files); @@ -1185,7 +1186,16 @@ asmlinkage long sys_close(unsigned int fd) FD_CLR(fd, fdt->close_on_exec); __put_unused_fd(files, fd); spin_unlock(&files->file_lock); - return filp_close(filp, files); + retval = filp_close(filp, files); + + /* can't restart close syscall because file table entry was cleared */ + if (unlikely(retval == -ERESTARTSYS || + retval == -ERESTARTNOINTR || + retval == -ERESTARTNOHAND || + retval == -ERESTART_RESTARTBLOCK)) + retval = -EINTR; + + return retval; out_unlock: spin_unlock(&files->file_lock); -- cgit v1.2.3 From 486ccb05fdbb7ca79784fdf0d07d2a86de48cf05 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 29 Sep 2006 02:00:24 -0700 Subject: [PATCH] elf_core_dump: don't take tasklist_lock do_each_thread() is rcu-safe, and all tasks which use this ->mm must sleep in wait_for_completion(&mm->core_done) at this point, so we can use RCU locks. Also, remove unneeded INIT_LIST_HEAD(new) before list_add(new, head). Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_elf.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index bb43da5cde5..6eb48e1446e 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1479,20 +1479,19 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) if (signr) { struct elf_thread_status *tmp; - read_lock(&tasklist_lock); + rcu_read_lock(); do_each_thread(g,p) if (current->mm == p->mm && current != p) { tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); if (!tmp) { - read_unlock(&tasklist_lock); + rcu_read_unlock(); goto cleanup; } - INIT_LIST_HEAD(&tmp->list); tmp->thread = p; list_add(&tmp->list, &thread_list); } while_each_thread(g,p); - read_unlock(&tasklist_lock); + rcu_read_unlock(); list_for_each(t, &thread_list) { struct elf_thread_status *tmp; int sz; -- cgit v1.2.3 From bce9a234ce7d8dddbfcec28e37ea58b5d8f6003d Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 29 Sep 2006 02:00:25 -0700 Subject: [PATCH] elf_fdpic_core_dump: don't take tasklist_lock do_each_thread() is rcu-safe, and all tasks which use this ->mm must sleep in wait_for_completion(&mm->core_done) at this point, so we can use RCU locks. Also, remove unneeded INIT_LIST_HEAD(new) before list_add(new, head). Signed-off-by: Oleg Nesterov Acked-By: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_elf_fdpic.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 2f336582922..f86d5c9ce5e 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -1597,20 +1597,19 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, if (signr) { struct elf_thread_status *tmp; - read_lock(&tasklist_lock); + rcu_read_lock(); do_each_thread(g,p) if (current->mm == p->mm && current != p) { tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); if (!tmp) { - read_unlock(&tasklist_lock); + rcu_read_unlock(); goto cleanup; } - INIT_LIST_HEAD(&tmp->list); tmp->thread = p; list_add(&tmp->list, &thread_list); } while_each_thread(g,p); - read_unlock(&tasklist_lock); + rcu_read_unlock(); list_for_each(t, &thread_list) { struct elf_thread_status *tmp; int sz; -- cgit v1.2.3 From b525a7e4445c4702dfc541930747517615c0c72a Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 29 Sep 2006 02:00:26 -0700 Subject: [PATCH] dquot: add proper locking when using current->signal->tty Dquot passes the tty to tty_write_message without locking Signed-off-by: Jan Kara Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/dquot.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'fs') diff --git a/fs/dquot.c b/fs/dquot.c index 0122a279106..9af789567e5 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -834,6 +834,9 @@ static void print_warning(struct dquot *dquot, const char warntype) if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags))) return; + mutex_lock(&tty_mutex); + if (!current->signal->tty) + goto out_lock; tty_write_message(current->signal->tty, dquot->dq_sb->s_id); if (warntype == ISOFTWARN || warntype == BSOFTWARN) tty_write_message(current->signal->tty, ": warning, "); @@ -861,6 +864,8 @@ static void print_warning(struct dquot *dquot, const char warntype) break; } tty_write_message(current->signal->tty, msg); +out_lock: + mutex_unlock(&tty_mutex); } static inline void flush_warnings(struct dquot **dquots, char *warntype) -- cgit v1.2.3 From fb50ae7446abb35184be029c51f825e45a4e0670 Mon Sep 17 00:00:00 2001 From: Joel & Rebecca VanderZee Date: Fri, 29 Sep 2006 02:00:30 -0700 Subject: [PATCH] I/O Error attempting to read last partial block of a file in an ISO9660 file system There was an I/O error that prevented reading the last partial block of large files in an ISO9660 filesystem. The error was generated when a file comprised more than one section and had a size that was not an exact multiple of the filesystem block size. This patch removes the check (and failure) for reading into the last partial block (and possibly beyond) for multiple-section files. It worked in my testing to prevent reading beyond the end of the section; my first patch just incremented the sect_size block count for a partial block and continued doing the check. But there is a commment in the source code about reading beyond the end of the file to fill a page cache. Failing to access beyond the section would prevent reading beyond the end of the file. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/isofs/inode.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'fs') diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 4527692f432..c34b862cdbf 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -960,30 +960,30 @@ int isofs_get_blocks(struct inode *inode, sector_t iblock_s, goto abort; } - if (nextblk) { - while (b_off >= (offset + sect_size)) { - struct inode *ninode; - - offset += sect_size; - if (nextblk == 0) - goto abort; - ninode = isofs_iget(inode->i_sb, nextblk, nextoff); - if (!ninode) - goto abort; - firstext = ISOFS_I(ninode)->i_first_extent; - sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode); - nextblk = ISOFS_I(ninode)->i_next_section_block; - nextoff = ISOFS_I(ninode)->i_next_section_offset; - iput(ninode); - - if (++section > 100) { - printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n"); - printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u " - "nextblk=%lu nextoff=%lu\n", - iblock, firstext, (unsigned) sect_size, - nextblk, nextoff); - goto abort; - } + /* On the last section, nextblk == 0, section size is likely to + * exceed sect_size by a partial block, and access beyond the + * end of the file will reach beyond the section size, too. + */ + while (nextblk && (b_off >= (offset + sect_size))) { + struct inode *ninode; + + offset += sect_size; + ninode = isofs_iget(inode->i_sb, nextblk, nextoff); + if (!ninode) + goto abort; + firstext = ISOFS_I(ninode)->i_first_extent; + sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode); + nextblk = ISOFS_I(ninode)->i_next_section_block; + nextoff = ISOFS_I(ninode)->i_next_section_offset; + iput(ninode); + + if (++section > 100) { + printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n"); + printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u " + "nextblk=%lu nextoff=%lu\n", + iblock, firstext, (unsigned) sect_size, + nextblk, nextoff); + goto abort; } } -- cgit v1.2.3 From 3cfd0885fac78c130a119ed576d18b5948fa2a5a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 29 Sep 2006 02:00:41 -0700 Subject: [PATCH] tty: stop the tty vanishing under procfs access Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/array.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'fs') diff --git a/fs/proc/array.c b/fs/proc/array.c index 0b615d62a15..c0e554971df 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -347,6 +347,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) sigemptyset(&sigign); sigemptyset(&sigcatch); cutime = cstime = utime = stime = cputime_zero; + + mutex_lock(&tty_mutex); read_lock(&tasklist_lock); if (task->sighand) { spin_lock_irq(&task->sighand->siglock); @@ -388,6 +390,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) } ppid = pid_alive(task) ? task->group_leader->real_parent->tgid : 0; read_unlock(&tasklist_lock); + mutex_unlock(&tty_mutex); if (!whole || num_threads<2) wchan = get_wchan(task); -- cgit v1.2.3 From cf3e43dbe0cc4a7ee7f6ab1bb5231dcfda164e02 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 29 Sep 2006 02:00:44 -0700 Subject: [PATCH] cdev documentation Add some documentation comments for the cdev interface. Signed-off-by: Jonathan Corbet Cc: Rolf Eike Beer Acked-by: "Randy.Dunlap" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/char_dev.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'fs') diff --git a/fs/char_dev.c b/fs/char_dev.c index 33b95af89da..1f3285affa3 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -183,6 +183,15 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct) return cd; } +/** + * register_chrdev_region() - register a range of device numbers + * @from: the first in the desired range of device numbers; must include + * the major number. + * @count: the number of consecutive device numbers required + * @name: the name of the device or driver. + * + * Return value is zero on success, a negative error code on failure. + */ int register_chrdev_region(dev_t from, unsigned count, const char *name) { struct char_device_struct *cd; @@ -208,6 +217,17 @@ fail: return PTR_ERR(cd); } +/** + * alloc_chrdev_region() - register a range of char device numbers + * @dev: output parameter for first assigned number + * @baseminor: first of the requested range of minor numbers + * @count: the number of minor numbers required + * @name: the name of the associated device or driver + * + * Allocates a range of char device numbers. The major number will be + * chosen dynamically, and returned (along with the first minor number) + * in @dev. Returns zero or a negative error code. + */ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name) { @@ -277,6 +297,15 @@ out2: return err; } +/** + * unregister_chrdev_region() - return a range of device numbers + * @from: the first in the range of numbers to unregister + * @count: the number of device numbers to unregister + * + * This function will unregister a range of @count device numbers, + * starting with @from. The caller should normally be the one who + * allocated those numbers in the first place... + */ void unregister_chrdev_region(dev_t from, unsigned count) { dev_t to = from + count; @@ -414,6 +443,16 @@ static int exact_lock(dev_t dev, void *data) return cdev_get(p) ? 0 : -1; } +/** + * cdev_add() - add a char device to the system + * @p: the cdev structure for the device + * @dev: the first device number for which this device is responsible + * @count: the number of consecutive minor numbers corresponding to this + * device + * + * cdev_add() adds the device represented by @p to the system, making it + * live immediately. A negative error code is returned on failure. + */ int cdev_add(struct cdev *p, dev_t dev, unsigned count) { p->dev = dev; @@ -426,6 +465,13 @@ static void cdev_unmap(dev_t dev, unsigned count) kobj_unmap(cdev_map, dev, count); } +/** + * cdev_del() - remove a cdev from the system + * @p: the cdev structure to be removed + * + * cdev_del() removes @p from the system, possibly freeing the structure + * itself. + */ void cdev_del(struct cdev *p) { cdev_unmap(p->dev, p->count); @@ -454,6 +500,11 @@ static struct kobj_type ktype_cdev_dynamic = { .release = cdev_dynamic_release, }; +/** + * cdev_alloc() - allocate a cdev structure + * + * Allocates and returns a cdev structure, or NULL on failure. + */ struct cdev *cdev_alloc(void) { struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); @@ -465,6 +516,14 @@ struct cdev *cdev_alloc(void) return p; } +/** + * cdev_init() - initialize a cdev structure + * @cdev: the structure to initialize + * @fops: the file_operations for this device + * + * Initializes @cdev, remembering @fops, making it ready to add to the + * system with cdev_add(). + */ void cdev_init(struct cdev *cdev, const struct file_operations *fops) { memset(cdev, 0, sizeof *cdev); -- cgit v1.2.3 From be3ca7fecb1a9903c6253f49aec0af2a0f3a04e4 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Fri, 29 Sep 2006 02:00:53 -0700 Subject: [PATCH] autofs4: autofs4_follow_link false negative fix The check for an empty directory in the autofs4_follow_link method fails occassionally due to old dentrys. We had the same problem autofs4_revalidate ages ago. I thought we wouldn't need this in autofs4_follow_link, silly me. Signed-off-by: Ian Kent Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/autofs4/root.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 27e17f96cad..0ec24835239 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -359,7 +359,7 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) * don't try to mount it again. */ spin_lock(&dcache_lock); - if (!d_mountpoint(dentry) && list_empty(&dentry->d_subdirs)) { + if (!d_mountpoint(dentry) && __simple_empty(dentry)) { spin_unlock(&dcache_lock); status = try_to_fill_dentry(dentry, 0); -- cgit v1.2.3 From 44938af6e08580514abce8bea23ae1c034ea0b1d Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Fri, 29 Sep 2006 02:00:54 -0700 Subject: [PATCH] autofs4: pending flag not cleared on mount fail During testing I've found that the mount pending flag can be left set at exit from autofs4_lookup after a failed mount request. This shouldn't be allowed to happen and causes incorrect error returns. Signed-off-by: Ian Kent Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/autofs4/root.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 0ec24835239..563ef9d7da9 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -281,9 +281,6 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags) DPRINTK("mount done status=%d", status); - if (status && dentry->d_inode) - return status; /* Try to get the kernel to invalidate this dentry */ - /* Turn this into a real negative dentry? */ if (status == -ENOENT) { spin_lock(&dentry->d_lock); @@ -540,6 +537,9 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s return ERR_PTR(-ERESTARTNOINTR); } } + spin_lock(&dentry->d_lock); + dentry->d_flags &= ~DCACHE_AUTOFS_PENDING; + spin_unlock(&dentry->d_lock); } /* -- cgit v1.2.3 From 87d7c8aca8670a772f74766c19e0345a606b67a9 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Fri, 29 Sep 2006 02:01:01 -0700 Subject: [PATCH] block_dev.c mutex_lock_nested() fix In the case below we are locking the whole disk not a partition. This change simply brings the code in line with the piece above where when we are the 'first' opener, and we are a partition. Signed-off-by: Jason Baron Acked-by: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/block_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/block_dev.c b/fs/block_dev.c index 8cc144ffc38..4346468139e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1031,7 +1031,7 @@ do_open(struct block_device *bdev, struct file *file, unsigned int subclass) rescan_partitions(bdev->bd_disk, bdev); } else { mutex_lock_nested(&bdev->bd_contains->bd_mutex, - BD_MUTEX_PARTITION); + BD_MUTEX_WHOLE); bdev->bd_contains->bd_part_count++; mutex_unlock(&bdev->bd_contains->bd_mutex); } -- cgit v1.2.3 From f7ca54f486d3b07f48b8bbc92705bde6ba98ee54 Mon Sep 17 00:00:00 2001 From: Frederik Deweerdt Date: Fri, 29 Sep 2006 02:01:02 -0700 Subject: [PATCH] fix mem_write() return value At the beginning of the routine, "copied" is set to 0, but it is no good because in lines 805 and 812 it is set to other values. Finally, the routine returns as if it copied 12 (=ENOMEM) bytes less than it actually did. Signed-off-by: Frederik Deweerdt Acked-by: Eric Biederman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/proc/base.c b/fs/proc/base.c index fe8d55fb17c..89c20d9d50b 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -797,7 +797,7 @@ out_no_task: static ssize_t mem_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { - int copied = 0; + int copied; char *page; struct task_struct *task = get_proc_task(file->f_dentry->d_inode); unsigned long dst = *ppos; @@ -814,6 +814,7 @@ static ssize_t mem_write(struct file * file, const char * buf, if (!page) goto out; + copied = 0; while (count > 0) { int this_len, retval; -- cgit v1.2.3 From 50d44ed009a628e6d5c784fae18ea743d7cf199a Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 29 Sep 2006 02:01:04 -0700 Subject: [PATCH] cramfs: rewrite init_cramfs_fs() Two lines -- two bugs. :-( Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/cramfs/inode.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index ad96b699071..a624c3ec818 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -543,8 +543,15 @@ static struct file_system_type cramfs_fs_type = { static int __init init_cramfs_fs(void) { - cramfs_uncompress_init(); - return register_filesystem(&cramfs_fs_type); + int rv; + + rv = cramfs_uncompress_init(); + if (rv < 0) + return rv; + rv = register_filesystem(&cramfs_fs_type); + if (rv < 0) + cramfs_uncompress_exit(); + return rv; } static void __exit exit_cramfs_fs(void) -- cgit v1.2.3 From a4376e13ce07774be14e83fe501ef5c8500b83a1 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 29 Sep 2006 02:01:04 -0700 Subject: [PATCH] freevxfs: fix leak on error path If register_filesystem() fails, vxfs_inode cache must be destroyed. Signed-off-by: Alexey Dobriyan Acked-by: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/freevxfs/vxfs_super.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index b74b791fc23..ac28b0835ff 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c @@ -260,12 +260,17 @@ static struct file_system_type vxfs_fs_type = { static int __init vxfs_init(void) { + int rv; + vxfs_inode_cachep = kmem_cache_create("vxfs_inode", sizeof(struct vxfs_inode_info), 0, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL, NULL); - if (vxfs_inode_cachep) - return register_filesystem(&vxfs_fs_type); - return -ENOMEM; + if (!vxfs_inode_cachep) + return -ENOMEM; + rv = register_filesystem(&vxfs_fs_type); + if (rv < 0) + kmem_cache_destroy(vxfs_inode_cachep); + return rv; } static void __exit -- cgit v1.2.3 From 368bdb3d616fa352971f45b423ae6344715e620b Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 29 Sep 2006 02:01:05 -0700 Subject: [PATCH] cramfs: make cramfs_uncompress_exit() return void It always returns 0, so relying on it is useless. The only caller isn't checking return value. In general, un-, de-, -free functions should return void. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/cramfs/uncompress.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index 8def89f2c43..fc3ccb74626 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c @@ -68,11 +68,10 @@ int cramfs_uncompress_init(void) return 0; } -int cramfs_uncompress_exit(void) +void cramfs_uncompress_exit(void) { if (!--initialized) { zlib_inflateEnd(&stream); vfree(stream.workspace); } - return 0; } -- cgit v1.2.3 From d826380b305971ff9825ef005ff039d655542bbb Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 29 Sep 2006 02:01:06 -0700 Subject: [PATCH] 9p: fix leak on error path If register_filesystem() fails mux workqueue must be killed. Signed-off-by: Alexey Dobriyan Cc: Eric Van Hensbergen Cc: Ron Minnich Cc: Latchesar Ionkov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/9p/v9fs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 22f7ccd58d3..0f628041e3f 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c @@ -460,8 +460,10 @@ static int __init init_v9fs(void) ret = v9fs_mux_global_init(); if (!ret) - ret = register_filesystem(&v9fs_fs_type); - + return ret; + ret = register_filesystem(&v9fs_fs_type); + if (!ret) + v9fs_mux_global_exit(); return ret; } -- cgit v1.2.3 From 6ea36ddbd1abfe867f1e874a8312bfd811e5fd2c Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 29 Sep 2006 02:01:07 -0700 Subject: [PATCH] Ban register_filesystem(NULL); Everyone passes valid pointer there. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/filesystems.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'fs') diff --git a/fs/filesystems.c b/fs/filesystems.c index 9f1072836c8..e3fa77c6ed5 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -69,8 +69,6 @@ int register_filesystem(struct file_system_type * fs) int res = 0; struct file_system_type ** p; - if (!fs) - return -EINVAL; if (fs->next) return -EBUSY; INIT_LIST_HEAD(&fs->fs_supers); -- cgit v1.2.3 From e518ddb7ba44a3d852c0e41961365844c76eb2bf Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Fri, 29 Sep 2006 02:01:22 -0700 Subject: [PATCH] fs/namei.c: replace multiple current->fs by shortcut variable Replace current->fs by fs helper variable to reduce some indirection overhead and (at least at the moment, before the current_thread_info() %gs PDA improvement is available) get rid of more costly current references. Reduces fs/namei.o from 37786 to 37082 Bytes (704 Bytes saved). [akpm@osdl.org: cleanup] Signed-off-by: Andreas Mohr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 86 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 39 deletions(-) (limited to 'fs') diff --git a/fs/namei.c b/fs/namei.c index 808e4ea2bb9..2892e68d3a8 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -518,18 +518,20 @@ static int __emul_lookup_dentry(const char *, struct nameidata *); static __always_inline int walk_init_root(const char *name, struct nameidata *nd) { - read_lock(¤t->fs->lock); - if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) { - nd->mnt = mntget(current->fs->altrootmnt); - nd->dentry = dget(current->fs->altroot); - read_unlock(¤t->fs->lock); + struct fs_struct *fs = current->fs; + + read_lock(&fs->lock); + if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { + nd->mnt = mntget(fs->altrootmnt); + nd->dentry = dget(fs->altroot); + read_unlock(&fs->lock); if (__emul_lookup_dentry(name,nd)) return 0; - read_lock(¤t->fs->lock); + read_lock(&fs->lock); } - nd->mnt = mntget(current->fs->rootmnt); - nd->dentry = dget(current->fs->root); - read_unlock(¤t->fs->lock); + nd->mnt = mntget(fs->rootmnt); + nd->dentry = dget(fs->root); + read_unlock(&fs->lock); return 1; } @@ -724,17 +726,19 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry) static __always_inline void follow_dotdot(struct nameidata *nd) { + struct fs_struct *fs = current->fs; + while(1) { struct vfsmount *parent; struct dentry *old = nd->dentry; - read_lock(¤t->fs->lock); - if (nd->dentry == current->fs->root && - nd->mnt == current->fs->rootmnt) { - read_unlock(¤t->fs->lock); + read_lock(&fs->lock); + if (nd->dentry == fs->root && + nd->mnt == fs->rootmnt) { + read_unlock(&fs->lock); break; } - read_unlock(¤t->fs->lock); + read_unlock(&fs->lock); spin_lock(&dcache_lock); if (nd->dentry != nd->mnt->mnt_root) { nd->dentry = dget(nd->dentry->d_parent); @@ -1042,15 +1046,17 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) struct vfsmount *old_mnt = nd->mnt; struct qstr last = nd->last; int last_type = nd->last_type; + struct fs_struct *fs = current->fs; + /* - * NAME was not found in alternate root or it's a directory. Try to find - * it in the normal root: + * NAME was not found in alternate root or it's a directory. + * Try to find it in the normal root: */ nd->last_type = LAST_ROOT; - read_lock(¤t->fs->lock); - nd->mnt = mntget(current->fs->rootmnt); - nd->dentry = dget(current->fs->root); - read_unlock(¤t->fs->lock); + read_lock(&fs->lock); + nd->mnt = mntget(fs->rootmnt); + nd->dentry = dget(fs->root); + read_unlock(&fs->lock); if (path_walk(name, nd) == 0) { if (nd->dentry->d_inode) { dput(old_dentry); @@ -1074,6 +1080,7 @@ void set_fs_altroot(void) struct vfsmount *mnt = NULL, *oldmnt; struct dentry *dentry = NULL, *olddentry; int err; + struct fs_struct *fs = current->fs; if (!emul) goto set_it; @@ -1083,12 +1090,12 @@ void set_fs_altroot(void) dentry = nd.dentry; } set_it: - write_lock(¤t->fs->lock); - oldmnt = current->fs->altrootmnt; - olddentry = current->fs->altroot; - current->fs->altrootmnt = mnt; - current->fs->altroot = dentry; - write_unlock(¤t->fs->lock); + write_lock(&fs->lock); + oldmnt = fs->altrootmnt; + olddentry = fs->altroot; + fs->altrootmnt = mnt; + fs->altroot = dentry; + write_unlock(&fs->lock); if (olddentry) { dput(olddentry); mntput(oldmnt); @@ -1102,29 +1109,30 @@ static int fastcall do_path_lookup(int dfd, const char *name, int retval = 0; int fput_needed; struct file *file; + struct fs_struct *fs = current->fs; nd->last_type = LAST_ROOT; /* if there are only slashes... */ nd->flags = flags; nd->depth = 0; if (*name=='/') { - read_lock(¤t->fs->lock); - if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) { - nd->mnt = mntget(current->fs->altrootmnt); - nd->dentry = dget(current->fs->altroot); - read_unlock(¤t->fs->lock); + read_lock(&fs->lock); + if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { + nd->mnt = mntget(fs->altrootmnt); + nd->dentry = dget(fs->altroot); + read_unlock(&fs->lock); if (__emul_lookup_dentry(name,nd)) goto out; /* found in altroot */ - read_lock(¤t->fs->lock); + read_lock(&fs->lock); } - nd->mnt = mntget(current->fs->rootmnt); - nd->dentry = dget(current->fs->root); - read_unlock(¤t->fs->lock); + nd->mnt = mntget(fs->rootmnt); + nd->dentry = dget(fs->root); + read_unlock(&fs->lock); } else if (dfd == AT_FDCWD) { - read_lock(¤t->fs->lock); - nd->mnt = mntget(current->fs->pwdmnt); - nd->dentry = dget(current->fs->pwd); - read_unlock(¤t->fs->lock); + read_lock(&fs->lock); + nd->mnt = mntget(fs->pwdmnt); + nd->dentry = dget(fs->pwd); + read_unlock(&fs->lock); } else { struct dentry *dentry; -- cgit v1.2.3 From 4e6fd33b75602ced4c5d43e99a10a1d13f33d4f4 Mon Sep 17 00:00:00 2001 From: Chris Snook Date: Fri, 29 Sep 2006 02:01:33 -0700 Subject: [PATCH] enforce RLIMIT_NOFILE in poll() POSIX states that poll() shall fail with EINVAL if nfds > OPEN_MAX. In this context, POSIX is referring to sysconf(OPEN_MAX), which is the value of current->signal->rlim[RLIMIT_NOFILE].rlim_cur in the linux kernel, not the compile-time constant which happens to also be named OPEN_MAX. In the current code, an application may poll up to max_fdset file descriptors, even if this exceeds RLIMIT_NOFILE. The current code also breaks applications which poll more than max_fdset descriptors, which worked circa 2.4.18 when the check was against NR_OPEN, which is 1024*1024. This patch enforces the limit precisely as POSIX defines, even if RLIMIT_NOFILE has been changed at run time with ulimit -n. To elaborate on the rationale for this, there are three cases: 1) RLIMIT_NOFILE is at the default value of 1024 In this (default) case, the patch changes nothing. Calls with nfds > 1024 fail with EINVAL both before and after the patch, and calls with nfds <= 1024 pass the check both before and after the patch, since 1024 is the initial value of max_fdset. 2) RLIMIT_NOFILE has been raised above the default In this case, poll() becomes more permissive, allowing polling up to RLIMIT_NOFILE file descriptors even if less than 1024 have been opened. The patch won't introduce new errors here. If an application somehow depends on poll() failing when it polls with duplicate or invalid file descriptors, it's already broken, since this is already allowed below 1024, and will also work above 1024 if enough file descriptors have been open at some point to cause max_fdset to have been increased above nfds. 3) RLIMIT_NOFILE has been lowered below the default In this case, the system administrator or the user has gone out of their way to protect the system from inefficient (or malicious) applications wasting kernel memory. The current code allows polling up to 1024 file descriptors even if RLIMIT_NOFILE is much lower, which is not what the user or administrator intended. Well-written applications which only poll valid, unique file descriptors will never notice the difference, because they'll hit the limit on open() first. If an application gets broken because of the patch in this case, then it was already poorly/maliciously designed, and allowing it to work in the past was a violation of POSIX and a DoS risk on low-resource systems. With this patch, poll() will permit exactly what POSIX suggests, no more, no less, and for any run-time value set with ulimit -n, not just 256 or 1024. There are existing apps which which poll a large number of file descriptors, some of which may be invalid, and if those numbers stradle 1024, they currently fail with or without the patch in -mm, though they worked fine under 2.4.18. Signed-off-by: Chris Snook Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/select.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/select.c b/fs/select.c index 33b72ba0f86..dcbc1112b7e 100644 --- a/fs/select.c +++ b/fs/select.c @@ -658,8 +658,6 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout) unsigned int i; struct poll_list *head; struct poll_list *walk; - struct fdtable *fdt; - int max_fdset; /* Allocate small arguments on the stack to save memory and be faster - use long to make sure the buffer is aligned properly on 64 bit archs to avoid unaligned access */ @@ -667,11 +665,7 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout) struct poll_list *stack_pp = NULL; /* Do a sanity check on nfds ... */ - rcu_read_lock(); - fdt = files_fdtable(current->files); - max_fdset = fdt->max_fdset; - rcu_read_unlock(); - if (nfds > max_fdset && nfds > OPEN_MAX) + if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur) return -EINVAL; poll_initwait(&table); -- cgit v1.2.3 From f0c8bd164e1a0585d7e46896553136b4f488bd19 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Fri, 29 Sep 2006 02:01:34 -0700 Subject: [PATCH] Generic infrastructure for acls The patches solve the following problem: We want to grant access to devices based on who is logged in from where, etc. This includes switching back and forth between multiple user sessions, etc. Using ACLs to define device access for logged-in users gives us all the flexibility we need in order to fully solve the problem. Device special files nowadays usually live on tmpfs, hence tmpfs ACLs. Different distros have come up with solutions that solve the problem to different degrees: SUSE uses a resource manager which tracks login sessions and sets ACLs on device inodes as appropriate. RedHat uses pam_console, which changes the primary file ownership to the logged-in user. Others use a set of groups that users must be in in order to be granted the appropriate accesses. The freedesktop.org project plans to implement a combination of a console-tracker and a HAL-device-list based solution to grant access to devices to users, and more distros will likely follow this approach. These patches have first been posted here on 2 February 2005, and again on 8 January 2006. We have been shipping them in SLES9 and SLES10 with no problems reported. The previous submission is archived here: http://lkml.org/lkml/2006/1/8/229 http://lkml.org/lkml/2006/1/8/230 http://lkml.org/lkml/2006/1/8/231 This patch: Add some infrastructure for access control lists on in-memory filesystems such as tmpfs. Signed-off-by: Andreas Gruenbacher Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/Kconfig | 4 ++ fs/Makefile | 1 + fs/generic_acl.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 fs/generic_acl.c (limited to 'fs') diff --git a/fs/Kconfig b/fs/Kconfig index d311198bba4..deb9eec9f6e 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1940,6 +1940,10 @@ config 9P_FS If unsure, say N. +config GENERIC_ACL + bool + select FS_POSIX_ACL + endmenu menu "Partition Types" diff --git a/fs/Makefile b/fs/Makefile index 89135428a53..46b8cfe497b 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o obj-$(CONFIG_FS_MBCACHE) += mbcache.o obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o xattr_acl.o obj-$(CONFIG_NFS_COMMON) += nfs_common/ +obj-$(CONFIG_GENERIC_ACL) += generic_acl.o obj-$(CONFIG_QUOTA) += dquot.o obj-$(CONFIG_QFMT_V1) += quota_v1.o diff --git a/fs/generic_acl.c b/fs/generic_acl.c new file mode 100644 index 00000000000..9ccb7894717 --- /dev/null +++ b/fs/generic_acl.c @@ -0,0 +1,197 @@ +/* + * fs/generic_acl.c + * + * (C) 2005 Andreas Gruenbacher + * + * This file is released under the GPL. + */ + +#include +#include +#include + +/** + * generic_acl_list - Generic xattr_handler->list() operation + * @ops: Filesystem specific getacl and setacl callbacks + */ +size_t +generic_acl_list(struct inode *inode, struct generic_acl_operations *ops, + int type, char *list, size_t list_size) +{ + struct posix_acl *acl; + const char *name; + size_t size; + + acl = ops->getacl(inode, type); + if (!acl) + return 0; + posix_acl_release(acl); + + switch(type) { + case ACL_TYPE_ACCESS: + name = POSIX_ACL_XATTR_ACCESS; + break; + + case ACL_TYPE_DEFAULT: + name = POSIX_ACL_XATTR_DEFAULT; + break; + + default: + return 0; + } + size = strlen(name) + 1; + if (list && size <= list_size) + memcpy(list, name, size); + return size; +} + +/** + * generic_acl_get - Generic xattr_handler->get() operation + * @ops: Filesystem specific getacl and setacl callbacks + */ +int +generic_acl_get(struct inode *inode, struct generic_acl_operations *ops, + int type, void *buffer, size_t size) +{ + struct posix_acl *acl; + int error; + + acl = ops->getacl(inode, type); + if (!acl) + return -ENODATA; + error = posix_acl_to_xattr(acl, buffer, size); + posix_acl_release(acl); + + return error; +} + +/** + * generic_acl_set - Generic xattr_handler->set() operation + * @ops: Filesystem specific getacl and setacl callbacks + */ +int +generic_acl_set(struct inode *inode, struct generic_acl_operations *ops, + int type, const void *value, size_t size) +{ + struct posix_acl *acl = NULL; + int error; + + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) + return -EPERM; + if (value) { + acl = posix_acl_from_xattr(value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } + if (acl) { + mode_t mode; + + error = posix_acl_valid(acl); + if (error) + goto failed; + switch(type) { + case ACL_TYPE_ACCESS: + mode = inode->i_mode; + error = posix_acl_equiv_mode(acl, &mode); + if (error < 0) + goto failed; + inode->i_mode = mode; + if (error == 0) { + posix_acl_release(acl); + acl = NULL; + } + break; + + case ACL_TYPE_DEFAULT: + if (!S_ISDIR(inode->i_mode)) { + error = -EINVAL; + goto failed; + } + break; + } + } + ops->setacl(inode, type, acl); + error = 0; +failed: + posix_acl_release(acl); + return error; +} + +/** + * generic_acl_init - Take care of acl inheritance at @inode create time + * @ops: Filesystem specific getacl and setacl callbacks + * + * Files created inside a directory with a default ACL inherit the + * directory's default ACL. + */ +int +generic_acl_init(struct inode *inode, struct inode *dir, + struct generic_acl_operations *ops) +{ + struct posix_acl *acl = NULL; + mode_t mode = inode->i_mode; + int error; + + inode->i_mode = mode & ~current->fs->umask; + if (!S_ISLNK(inode->i_mode)) + acl = ops->getacl(dir, ACL_TYPE_DEFAULT); + if (acl) { + struct posix_acl *clone; + + if (S_ISDIR(inode->i_mode)) { + clone = posix_acl_clone(acl, GFP_KERNEL); + error = -ENOMEM; + if (!clone) + goto cleanup; + ops->setacl(inode, ACL_TYPE_DEFAULT, clone); + posix_acl_release(clone); + } + clone = posix_acl_clone(acl, GFP_KERNEL); + error = -ENOMEM; + if (!clone) + goto cleanup; + error = posix_acl_create_masq(clone, &mode); + if (error >= 0) { + inode->i_mode = mode; + if (error > 0) + ops->setacl(inode, ACL_TYPE_ACCESS, clone); + } + posix_acl_release(clone); + } + error = 0; + +cleanup: + posix_acl_release(acl); + return error; +} + +/** + * generic_acl_chmod - change the access acl of @inode upon chmod() + * @ops: FIlesystem specific getacl and setacl callbacks + * + * A chmod also changes the permissions of the owner, group/mask, and + * other ACL entries. + */ +int +generic_acl_chmod(struct inode *inode, struct generic_acl_operations *ops) +{ + struct posix_acl *acl, *clone; + int error = 0; + + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + acl = ops->getacl(inode, ACL_TYPE_ACCESS); + if (acl) { + clone = posix_acl_clone(acl, GFP_KERNEL); + posix_acl_release(acl); + if (!clone) + return -ENOMEM; + error = posix_acl_chmod_masq(clone, inode->i_mode); + if (!error) + ops->setacl(inode, ACL_TYPE_ACCESS, clone); + posix_acl_release(clone); + } + return error; +} -- cgit v1.2.3 From 39f0247d3823e4e0bf8f6838a10362864b1e1053 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Fri, 29 Sep 2006 02:01:35 -0700 Subject: [PATCH] Access Control Lists for tmpfs Add access control lists for tmpfs. Signed-off-by: Andreas Gruenbacher Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/Kconfig | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'fs') diff --git a/fs/Kconfig b/fs/Kconfig index deb9eec9f6e..4fd9efac29a 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -881,6 +881,19 @@ config TMPFS See for details. +config TMPFS_POSIX_ACL + bool "Tmpfs POSIX Access Control Lists" + depends on TMPFS + select GENERIC_ACL + help + POSIX Access Control Lists (ACLs) support permissions for users and + groups beyond the owner/group/world scheme. + + To learn more about Access Control Lists, visit the POSIX ACLs for + Linux website . + + If you don't know what Access Control Lists are, say N. + config HUGETLBFS bool "HugeTLB file system support" depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN -- cgit v1.2.3 From 74d392aaabfc890cc1f0e80fc5ff13e5d3bcf4c9 Mon Sep 17 00:00:00 2001 From: Vadim Lobanov Date: Fri, 29 Sep 2006 02:01:43 -0700 Subject: [PATCH] Clean up expand_fdtable() and expand_files() Perform a code cleanup against the expand_fdtable() and expand_files() functions inside fs/file.c. It aims to make the flow of code within these functions simpler and easier to understand, via added comments and modest refactoring. Signed-off-by: Vadim Lobanov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/file.c | 76 +++++++++++++++++++++++++++++---------------------------------- 1 file changed, 35 insertions(+), 41 deletions(-) (limited to 'fs') diff --git a/fs/file.c b/fs/file.c index 8d3bfca7714..2a991ac8e56 100644 --- a/fs/file.c +++ b/fs/file.c @@ -288,71 +288,65 @@ out: } /* - * Expands the file descriptor table - it will allocate a new fdtable and - * both fd array and fdset. It is expected to be called with the - * files_lock held. + * Expand the file descriptor table. + * This function will allocate a new fdtable and both fd array and fdset, of + * the given size. + * Return <0 error code on error; 1 on successful completion. + * The files->file_lock should be held on entry, and will be held on exit. */ static int expand_fdtable(struct files_struct *files, int nr) __releases(files->file_lock) __acquires(files->file_lock) { - int error = 0; - struct fdtable *fdt; - struct fdtable *nfdt = NULL; + struct fdtable *new_fdt, *cur_fdt; spin_unlock(&files->file_lock); - nfdt = alloc_fdtable(nr); - if (!nfdt) { - error = -ENOMEM; - spin_lock(&files->file_lock); - goto out; - } - + new_fdt = alloc_fdtable(nr); spin_lock(&files->file_lock); - fdt = files_fdtable(files); + if (!new_fdt) + return -ENOMEM; /* - * Check again since another task may have expanded the - * fd table while we dropped the lock + * Check again since another task may have expanded the fd table while + * we dropped the lock */ - if (nr >= fdt->max_fds || nr >= fdt->max_fdset) { - copy_fdtable(nfdt, fdt); + cur_fdt = files_fdtable(files); + if (nr >= cur_fdt->max_fds || nr >= cur_fdt->max_fdset) { + /* Continue as planned */ + copy_fdtable(new_fdt, cur_fdt); + rcu_assign_pointer(files->fdt, new_fdt); + free_fdtable(cur_fdt); } else { - /* Somebody expanded while we dropped file_lock */ + /* Somebody else expanded, so undo our attempt */ spin_unlock(&files->file_lock); - __free_fdtable(nfdt); + __free_fdtable(new_fdt); spin_lock(&files->file_lock); - goto out; } - rcu_assign_pointer(files->fdt, nfdt); - free_fdtable(fdt); -out: - return error; + return 1; } /* * Expand files. - * Return <0 on error; 0 nothing done; 1 files expanded, we may have blocked. - * Should be called with the files->file_lock spinlock held for write. + * This function will expand the file structures, if the requested size exceeds + * the current capacity and there is room for expansion. + * Return <0 error code on error; 0 when nothing done; 1 when files were + * expanded and execution may have blocked. + * The files->file_lock should be held on entry, and will be held on exit. */ int expand_files(struct files_struct *files, int nr) { - int err, expand = 0; struct fdtable *fdt; fdt = files_fdtable(files); - if (nr >= fdt->max_fdset || nr >= fdt->max_fds) { - if (fdt->max_fdset >= NR_OPEN || - fdt->max_fds >= NR_OPEN || nr >= NR_OPEN) { - err = -EMFILE; - goto out; - } - expand = 1; - if ((err = expand_fdtable(files, nr))) - goto out; - } - err = expand; -out: - return err; + /* Do we need to expand? */ + if (nr < fdt->max_fdset && nr < fdt->max_fds) + return 0; + /* Can we expand? */ + if (fdt->max_fdset >= NR_OPEN || fdt->max_fds >= NR_OPEN || + nr >= NR_OPEN) + return -EMFILE; + + /* All good, so we try */ + return expand_fdtable(files, nr); } static void __devinit fdtable_defer_list_init(int cpu) -- cgit v1.2.3 From 327dcaadc0bc08ad081aa8e36b6ec7ad7aa45e30 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 29 Sep 2006 02:01:44 -0700 Subject: [PATCH] expand_fdtable(): remove pointless unlock+lock This unlock/lock on a super-unlikely path isn't worth the kernel text. Cc: Vadim Lobanov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/file.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'fs') diff --git a/fs/file.c b/fs/file.c index 2a991ac8e56..8e81775c5dc 100644 --- a/fs/file.c +++ b/fs/file.c @@ -317,9 +317,7 @@ static int expand_fdtable(struct files_struct *files, int nr) free_fdtable(cur_fdt); } else { /* Somebody else expanded, so undo our attempt */ - spin_unlock(&files->file_lock); __free_fdtable(new_fdt); - spin_lock(&files->file_lock); } return 1; } -- cgit v1.2.3 From 632dd2053a1146c826ceb6f26ab689389c05e751 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Fri, 29 Sep 2006 02:01:45 -0700 Subject: [PATCH] Kcore elf note namesz field fix o As per ELF specifications, it looks like that elf note "namesz" field contains the length of "name" including the size of null character. And currently we are filling "namesz" without taking into the consideration the null character size. o Kexec-tools performs this check deligently hence I ran into the issue while trying to open /proc/kcore in kexec-tools for some info. Signed-off-by: Vivek Goyal Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/kcore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 3ceff385727..1294eda4aca 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -100,7 +100,7 @@ static int notesize(struct memelfnote *en) int sz; sz = sizeof(struct elf_note); - sz += roundup(strlen(en->name), 4); + sz += roundup((strlen(en->name) + 1), 4); sz += roundup(en->datasz, 4); return sz; @@ -116,7 +116,7 @@ static char *storenote(struct memelfnote *men, char *bufp) #define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0) - en.n_namesz = strlen(men->name); + en.n_namesz = strlen(men->name) + 1; en.n_descsz = men->datasz; en.n_type = men->type; -- cgit v1.2.3 From fc46379daf90dce57bf765c81d3b39f55150aac2 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 29 Aug 2006 09:05:44 +0200 Subject: [PATCH] cfq-iosched: kill cfq_exit_lock cfq_exit_lock is protecting two things now: - The per-ioc rbtree of cfq_io_contexts - The per-cfqd linked list of cfq_io_contexts The per-cfqd linked list can be protected by the queue lock, as it is (by definition) per cfqd as the queue lock is. The per-ioc rbtree is mainly used and updated by the process itself only. The only outside use is the io priority changing. If we move the priority changing to not browsing the rbtree, we can remove any locking from the rbtree updates and lookup completely. Let the sys_ioprio syscall just mark processes as having the iopriority changed and lazily update the private cfq io contexts the next time io is queued, and we can remove this locking as well. Signed-off-by: Jens Axboe --- fs/ioprio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/ioprio.c b/fs/ioprio.c index 78b1deae3fa..0fd1089d7bf 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c @@ -47,8 +47,8 @@ static int set_task_ioprio(struct task_struct *task, int ioprio) /* see wmb() in current_io_context() */ smp_read_barrier_depends(); - if (ioc && ioc->set_ioprio) - ioc->set_ioprio(ioc, ioprio); + if (ioc) + ioc->ioprio_changed = 1; task_unlock(task); return 0; -- cgit v1.2.3 From caa38fb0f481a3cb732b115cb59bfa6b59b6daaf Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 23 Jul 2006 01:41:26 +0200 Subject: [PATCH] ext3: make meta data reads use READ_META Signed-off-by: Jens Axboe --- fs/ext3/inode.c | 5 +++-- fs/ext3/namei.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index dcf4f1dd108..03ba5bcab18 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "xattr.h" #include "acl.h" @@ -1073,7 +1074,7 @@ struct buffer_head *ext3_bread(handle_t *handle, struct inode *inode, return bh; if (buffer_uptodate(bh)) return bh; - ll_rw_block(READ, 1, &bh); + ll_rw_block(READ_META, 1, &bh); wait_on_buffer(bh); if (buffer_uptodate(bh)) return bh; @@ -2540,7 +2541,7 @@ make_io: */ get_bh(bh); bh->b_end_io = end_buffer_read_sync; - submit_bh(READ, bh); + submit_bh(READ_META, bh); wait_on_buffer(bh); if (!buffer_uptodate(bh)) { ext3_error(inode->i_sb, "ext3_get_inode_loc", diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 85d132c37ee..235e77b52ea 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "namei.h" @@ -870,7 +871,7 @@ restart: bh = ext3_getblk(NULL, dir, b++, 0, &err); bh_use[ra_max] = bh; if (bh) - ll_rw_block(READ, 1, &bh); + ll_rw_block(READ_META, 1, &bh); } } if ((bh = bh_use[ra_ptr++]) == NULL) -- cgit v1.2.3 From cf342e52e3117391868fb4bd900ce772a27a5a1a Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 Aug 2006 09:17:41 +0200 Subject: [PATCH] Don't need to disable interrupts for tasklist_lock Signed-off-by: Oleg Nesterov Signed-off-by: Jens Axboe --- fs/ioprio.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/ioprio.c b/fs/ioprio.c index 0fd1089d7bf..03dc4f269b7 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c @@ -81,7 +81,12 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) } ret = -ESRCH; - read_lock_irq(&tasklist_lock); + /* + * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic", + * so we can't use rcu_read_lock(). See re-copy of ->ioprio + * in copy_process(). + */ + read_lock(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: if (!who) @@ -124,7 +129,7 @@ free_uid: ret = -EINVAL; } - read_unlock_irq(&tasklist_lock); + read_unlock(&tasklist_lock); return ret; } @@ -170,7 +175,7 @@ asmlinkage long sys_ioprio_get(int which, int who) int ret = -ESRCH; int tmpio; - read_lock_irq(&tasklist_lock); + read_lock(&tasklist_lock); switch (which) { case IOPRIO_WHO_PROCESS: if (!who) @@ -221,7 +226,7 @@ asmlinkage long sys_ioprio_get(int which, int who) ret = -EINVAL; } - read_unlock_irq(&tasklist_lock); + read_unlock(&tasklist_lock); return ret; } -- cgit v1.2.3 From cf9a2ae8d49948f861b56e5333530e491a9da190 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:05:54 +0100 Subject: [PATCH] BLOCK: Move functions out of buffer code [try #6] Move some functions out of the buffering code that aren't strictly buffering specific. This is a precursor to being able to disable the block layer. (*) Moved some stuff out of fs/buffer.c: (*) The file sync and general sync stuff moved to fs/sync.c. (*) The superblock sync stuff moved to fs/super.c. (*) do_invalidatepage() moved to mm/truncate.c. (*) try_to_release_page() moved to mm/filemap.c. (*) Moved some related declarations between header files: (*) declarations for do_invalidatepage() and try_to_release_page() moved to linux/mm.h. (*) __set_page_dirty_buffers() moved to linux/buffer_head.h. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/buffer.c | 174 ------------------------------------------------------------ fs/super.c | 31 +++++++++++ fs/sync.c | 113 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 174 deletions(-) (limited to 'fs') diff --git a/fs/buffer.c b/fs/buffer.c index 3b6d701073e..16cfbcd254f 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -159,31 +159,6 @@ int sync_blockdev(struct block_device *bdev) } EXPORT_SYMBOL(sync_blockdev); -static void __fsync_super(struct super_block *sb) -{ - sync_inodes_sb(sb, 0); - DQUOT_SYNC(sb); - lock_super(sb); - if (sb->s_dirt && sb->s_op->write_super) - sb->s_op->write_super(sb); - unlock_super(sb); - if (sb->s_op->sync_fs) - sb->s_op->sync_fs(sb, 1); - sync_blockdev(sb->s_bdev); - sync_inodes_sb(sb, 1); -} - -/* - * Write out and wait upon all dirty data associated with this - * superblock. Filesystem data as well as the underlying block - * device. Takes the superblock lock. - */ -int fsync_super(struct super_block *sb) -{ - __fsync_super(sb); - return sync_blockdev(sb->s_bdev); -} - /* * Write out and wait upon all dirty data associated with this * device. Filesystem data as well as the underlying block @@ -259,118 +234,6 @@ void thaw_bdev(struct block_device *bdev, struct super_block *sb) } EXPORT_SYMBOL(thaw_bdev); -/* - * sync everything. Start out by waking pdflush, because that writes back - * all queues in parallel. - */ -static void do_sync(unsigned long wait) -{ - wakeup_pdflush(0); - sync_inodes(0); /* All mappings, inodes and their blockdevs */ - DQUOT_SYNC(NULL); - sync_supers(); /* Write the superblocks */ - sync_filesystems(0); /* Start syncing the filesystems */ - sync_filesystems(wait); /* Waitingly sync the filesystems */ - sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */ - if (!wait) - printk("Emergency Sync complete\n"); - if (unlikely(laptop_mode)) - laptop_sync_completion(); -} - -asmlinkage long sys_sync(void) -{ - do_sync(1); - return 0; -} - -void emergency_sync(void) -{ - pdflush_operation(do_sync, 0); -} - -/* - * Generic function to fsync a file. - * - * filp may be NULL if called via the msync of a vma. - */ - -int file_fsync(struct file *filp, struct dentry *dentry, int datasync) -{ - struct inode * inode = dentry->d_inode; - struct super_block * sb; - int ret, err; - - /* sync the inode to buffers */ - ret = write_inode_now(inode, 0); - - /* sync the superblock to buffers */ - sb = inode->i_sb; - lock_super(sb); - if (sb->s_op->write_super) - sb->s_op->write_super(sb); - unlock_super(sb); - - /* .. finally sync the buffers to disk */ - err = sync_blockdev(sb->s_bdev); - if (!ret) - ret = err; - return ret; -} - -long do_fsync(struct file *file, int datasync) -{ - int ret; - int err; - struct address_space *mapping = file->f_mapping; - - if (!file->f_op || !file->f_op->fsync) { - /* Why? We can still call filemap_fdatawrite */ - ret = -EINVAL; - goto out; - } - - ret = filemap_fdatawrite(mapping); - - /* - * We need to protect against concurrent writers, which could cause - * livelocks in fsync_buffers_list(). - */ - mutex_lock(&mapping->host->i_mutex); - err = file->f_op->fsync(file, file->f_dentry, datasync); - if (!ret) - ret = err; - mutex_unlock(&mapping->host->i_mutex); - err = filemap_fdatawait(mapping); - if (!ret) - ret = err; -out: - return ret; -} - -static long __do_fsync(unsigned int fd, int datasync) -{ - struct file *file; - int ret = -EBADF; - - file = fget(fd); - if (file) { - ret = do_fsync(file, datasync); - fput(file); - } - return ret; -} - -asmlinkage long sys_fsync(unsigned int fd) -{ - return __do_fsync(fd, 0); -} - -asmlinkage long sys_fdatasync(unsigned int fd) -{ - return __do_fsync(fd, 1); -} - /* * Various filesystems appear to want __find_get_block to be non-blocking. * But it's the page lock which protects the buffers. To get around this, @@ -1550,35 +1413,6 @@ static void discard_buffer(struct buffer_head * bh) unlock_buffer(bh); } -/** - * try_to_release_page() - release old fs-specific metadata on a page - * - * @page: the page which the kernel is trying to free - * @gfp_mask: memory allocation flags (and I/O mode) - * - * The address_space is to try to release any data against the page - * (presumably at page->private). If the release was successful, return `1'. - * Otherwise return zero. - * - * The @gfp_mask argument specifies whether I/O may be performed to release - * this page (__GFP_IO), and whether the call may block (__GFP_WAIT). - * - * NOTE: @gfp_mask may go away, and this function may become non-blocking. - */ -int try_to_release_page(struct page *page, gfp_t gfp_mask) -{ - struct address_space * const mapping = page->mapping; - - BUG_ON(!PageLocked(page)); - if (PageWriteback(page)) - return 0; - - if (mapping && mapping->a_ops->releasepage) - return mapping->a_ops->releasepage(page, gfp_mask); - return try_to_free_buffers(page); -} -EXPORT_SYMBOL(try_to_release_page); - /** * block_invalidatepage - invalidate part of all of a buffer-backed page * @@ -1630,14 +1464,6 @@ out: } EXPORT_SYMBOL(block_invalidatepage); -void do_invalidatepage(struct page *page, unsigned long offset) -{ - void (*invalidatepage)(struct page *, unsigned long); - invalidatepage = page->mapping->a_ops->invalidatepage ? : - block_invalidatepage; - (*invalidatepage)(page, offset); -} - /* * We attach and possibly dirty the buffers atomically wrt * __set_page_dirty_buffers() via private_lock. try_to_free_buffers diff --git a/fs/super.c b/fs/super.c index 6987824d0dc..15671cd048b 100644 --- a/fs/super.c +++ b/fs/super.c @@ -220,6 +220,37 @@ static int grab_super(struct super_block *s) __releases(sb_lock) return 0; } +/* + * Write out and wait upon all dirty data associated with this + * superblock. Filesystem data as well as the underlying block + * device. Takes the superblock lock. Requires a second blkdev + * flush by the caller to complete the operation. + */ +void __fsync_super(struct super_block *sb) +{ + sync_inodes_sb(sb, 0); + DQUOT_SYNC(sb); + lock_super(sb); + if (sb->s_dirt && sb->s_op->write_super) + sb->s_op->write_super(sb); + unlock_super(sb); + if (sb->s_op->sync_fs) + sb->s_op->sync_fs(sb, 1); + sync_blockdev(sb->s_bdev); + sync_inodes_sb(sb, 1); +} + +/* + * Write out and wait upon all dirty data associated with this + * superblock. Filesystem data as well as the underlying block + * device. Takes the superblock lock. + */ +int fsync_super(struct super_block *sb) +{ + __fsync_super(sb); + return sync_blockdev(sb->s_bdev); +} + /** * generic_shutdown_super - common helper for ->kill_sb() * @sb: superblock to kill diff --git a/fs/sync.c b/fs/sync.c index 955aef04da2..1de747b5ddb 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -10,10 +10,123 @@ #include #include #include +#include +#include #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ SYNC_FILE_RANGE_WAIT_AFTER) +/* + * sync everything. Start out by waking pdflush, because that writes back + * all queues in parallel. + */ +static void do_sync(unsigned long wait) +{ + wakeup_pdflush(0); + sync_inodes(0); /* All mappings, inodes and their blockdevs */ + DQUOT_SYNC(NULL); + sync_supers(); /* Write the superblocks */ + sync_filesystems(0); /* Start syncing the filesystems */ + sync_filesystems(wait); /* Waitingly sync the filesystems */ + sync_inodes(wait); /* Mappings, inodes and blockdevs, again. */ + if (!wait) + printk("Emergency Sync complete\n"); + if (unlikely(laptop_mode)) + laptop_sync_completion(); +} + +asmlinkage long sys_sync(void) +{ + do_sync(1); + return 0; +} + +void emergency_sync(void) +{ + pdflush_operation(do_sync, 0); +} + +/* + * Generic function to fsync a file. + * + * filp may be NULL if called via the msync of a vma. + */ +int file_fsync(struct file *filp, struct dentry *dentry, int datasync) +{ + struct inode * inode = dentry->d_inode; + struct super_block * sb; + int ret, err; + + /* sync the inode to buffers */ + ret = write_inode_now(inode, 0); + + /* sync the superblock to buffers */ + sb = inode->i_sb; + lock_super(sb); + if (sb->s_op->write_super) + sb->s_op->write_super(sb); + unlock_super(sb); + + /* .. finally sync the buffers to disk */ + err = sync_blockdev(sb->s_bdev); + if (!ret) + ret = err; + return ret; +} + +long do_fsync(struct file *file, int datasync) +{ + int ret; + int err; + struct address_space *mapping = file->f_mapping; + + if (!file->f_op || !file->f_op->fsync) { + /* Why? We can still call filemap_fdatawrite */ + ret = -EINVAL; + goto out; + } + + ret = filemap_fdatawrite(mapping); + + /* + * We need to protect against concurrent writers, which could cause + * livelocks in fsync_buffers_list(). + */ + mutex_lock(&mapping->host->i_mutex); + err = file->f_op->fsync(file, file->f_dentry, datasync); + if (!ret) + ret = err; + mutex_unlock(&mapping->host->i_mutex); + err = filemap_fdatawait(mapping); + if (!ret) + ret = err; +out: + return ret; +} + +static long __do_fsync(unsigned int fd, int datasync) +{ + struct file *file; + int ret = -EBADF; + + file = fget(fd); + if (file) { + ret = do_fsync(file, datasync); + fput(file); + } + return ret; +} + +asmlinkage long sys_fsync(unsigned int fd) +{ + return __do_fsync(fd, 0); +} + +asmlinkage long sys_fdatasync(unsigned int fd) +{ + return __do_fsync(fd, 1); +} + /* * sys_sync_file_range() permits finely controlled syncing over a segment of * a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is -- cgit v1.2.3 From 65e6f5bc8149165efb9d7bdbd142bb837d5edfeb Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:03 +0100 Subject: [PATCH] BLOCK: Don't call block_sync_page() from AFS [try #6] The AFS filesystem no longer needs to override its sync_page() op. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/afs/file.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs') diff --git a/fs/afs/file.c b/fs/afs/file.c index 67d6634101f..02264560d17 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -37,7 +37,6 @@ struct inode_operations afs_file_inode_operations = { const struct address_space_operations afs_fs_aops = { .readpage = afs_file_readpage, - .sync_page = block_sync_page, .set_page_dirty = __set_page_dirty_nobuffers, .releasepage = afs_file_releasepage, .invalidatepage = afs_file_invalidatepage, -- cgit v1.2.3 From 07f3f05c1e3052b8656129b2a5aca9f888241a34 Mon Sep 17 00:00:00 2001 From: David Howells Date: Sat, 30 Sep 2006 20:52:18 +0200 Subject: [PATCH] BLOCK: Move extern declarations out of fs/*.c into header files [try #6] Create a new header file, fs/internal.h, for common definitions local to the sources in the fs/ directory. Move extern definitions that should be in header files from fs/*.c to fs/internal.h or other main header files where they span directories. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/binfmt_elf.c | 1 - fs/block_dev.c | 1 + fs/char_dev.c | 1 + fs/compat.c | 10 +++------- fs/compat_ioctl.c | 2 -- fs/dcache.c | 4 +--- fs/fs-writeback.c | 3 +-- fs/internal.h | 36 ++++++++++++++++++++++++++++++++++++ fs/namespace.c | 3 +-- 9 files changed, 44 insertions(+), 17 deletions(-) create mode 100644 fs/internal.h (limited to 'fs') diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 6eb48e1446e..bad52433de6 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -46,7 +46,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_library(struct file *); static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); -extern int dump_fpu (struct pt_regs *, elf_fpregset_t *); #ifndef elf_addr_t #define elf_addr_t unsigned long diff --git a/fs/block_dev.c b/fs/block_dev.c index 4346468139e..20f7333ba37 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -22,6 +22,7 @@ #include #include #include +#include "internal.h" struct bdev_inode { struct block_device bdev; diff --git a/fs/char_dev.c b/fs/char_dev.c index 1f3285affa3..a885f46ca00 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -24,6 +24,7 @@ #ifdef CONFIG_KMOD #include #endif +#include "internal.h" /* * capabilities for /dev/mem, /dev/kmem and similar directly mappable character diff --git a/fs/compat.c b/fs/compat.c index ce982f6e8c8..122b4e3992b 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -52,11 +52,12 @@ #include #include #include - -extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); +#include "internal.h" int compat_log = 1; +extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); + int compat_printk(const char *fmt, ...) { va_list ap; @@ -313,9 +314,6 @@ out: #define IOCTL_HASHSIZE 256 static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; -extern struct ioctl_trans ioctl_start[]; -extern int ioctl_table_size; - static inline unsigned long ioctl32_hash(unsigned long cmd) { return (((cmd >> 6) ^ (cmd >> 4) ^ cmd)) % IOCTL_HASHSIZE; @@ -838,8 +836,6 @@ static int do_nfs4_super_data_conv(void *raw_data) return 0; } -extern int copy_mount_options (const void __user *, unsigned long *); - #define SMBFS_NAME "smbfs" #define NCPFS_NAME "ncpfs" #define NFS4_NAME "nfs4" diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 4063a939697..ab74c9bd55f 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -1279,8 +1279,6 @@ static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg) return err; } -extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); - #ifdef CONFIG_VT static int vt_check(struct file *file) diff --git a/fs/dcache.c b/fs/dcache.c index 17b392a2049..fc2faa44f8d 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -32,6 +32,7 @@ #include #include #include +#include "internal.h" int sysctl_vfs_cache_pressure __read_mostly = 100; @@ -1877,9 +1878,6 @@ kmem_cache_t *filp_cachep __read_mostly; EXPORT_SYMBOL(d_genocide); -extern void bdev_cache_init(void); -extern void chrdev_init(void); - void __init vfs_caches_init_early(void) { dcache_init_early(); diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 892643dc9af..0639024d83a 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -22,8 +22,7 @@ #include #include #include - -extern struct super_block *blockdev_superblock; +#include "internal.h" /** * __mark_inode_dirty - internal function diff --git a/fs/internal.h b/fs/internal.h new file mode 100644 index 00000000000..c21ecd37b1e --- /dev/null +++ b/fs/internal.h @@ -0,0 +1,36 @@ +/* fs/ internal definitions + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include + +/* + * block_dev.c + */ +extern struct super_block *blockdev_superblock; +extern void __init bdev_cache_init(void); + +/* + * char_dev.c + */ +extern void __init chrdev_init(void); + +/* + * compat_ioctl.c + */ +#ifdef CONFIG_COMPAT +extern struct ioctl_trans ioctl_start[]; +extern int ioctl_table_size; +#endif + +/* + * namespace.c + */ +extern int copy_mount_options(const void __user *, unsigned long *); diff --git a/fs/namespace.c b/fs/namespace.c index 6ede3a539ed..66d921e14fe 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -24,12 +24,11 @@ #include #include #include +#include #include #include #include "pnode.h" -extern int __init init_rootfs(void); - /* spinlock for vfsmount related operations, inplace of dcache_lock */ __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); -- cgit v1.2.3 From 7b0de42d7c5a471741ede4e71727d88000e6ea59 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:07 +0100 Subject: [PATCH] BLOCK: Remove dependence on existence of blockdev_superblock [try #6] Move blockdev_superblock extern declaration from fs/fs-writeback.c to a headerfile and remove the dependence on it by wrapping it in a macro. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/fs-writeback.c | 6 +++--- fs/internal.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 0639024d83a..c403b66ec83 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -319,7 +319,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) if (!bdi_cap_writeback_dirty(bdi)) { list_move(&inode->i_list, &sb->s_dirty); - if (sb == blockdev_superblock) { + if (sb_is_blkdev_sb(sb)) { /* * Dirty memory-backed blockdev: the ramdisk * driver does this. Skip just this inode @@ -336,14 +336,14 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) if (wbc->nonblocking && bdi_write_congested(bdi)) { wbc->encountered_congestion = 1; - if (sb != blockdev_superblock) + if (!sb_is_blkdev_sb(sb)) break; /* Skip a congested fs */ list_move(&inode->i_list, &sb->s_dirty); continue; /* Skip a congested blockdev */ } if (wbc->bdi && bdi != wbc->bdi) { - if (sb != blockdev_superblock) + if (!sb_is_blkdev_sb(sb)) break; /* fs has the wrong queue */ list_move(&inode->i_list, &sb->s_dirty); continue; /* blockdev has wrong queue */ diff --git a/fs/internal.h b/fs/internal.h index c21ecd37b1e..f662b703bb9 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -17,6 +17,8 @@ extern struct super_block *blockdev_superblock; extern void __init bdev_cache_init(void); +#define sb_is_blkdev_sb(sb) ((sb) == blockdev_superblock) + /* * char_dev.c */ -- cgit v1.2.3 From 811d736f9e8013966e1a5a930c0db09508bdbb15 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:09 +0100 Subject: [PATCH] BLOCK: Dissociate generic_writepages() from mpage stuff [try #6] Dissociate the generic_writepages() function from the mpage stuff, moving its declaration to linux/mm.h and actually emitting a full implementation into mm/page-writeback.c. The implementation is a partial duplicate of mpage_writepages() with all BIO references removed. It is used by NFS to do writeback. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/block_dev.c | 1 + fs/mpage.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'fs') diff --git a/fs/block_dev.c b/fs/block_dev.c index 20f7333ba37..335c38bb86e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/fs/mpage.c b/fs/mpage.c index 1e4598247d0..692a3e578fc 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -693,6 +693,8 @@ out: * the call was made get new I/O started against them. If wbc->sync_mode is * WB_SYNC_ALL then we were called for data integrity and we must wait for * existing IO to complete. + * + * If you fix this you should check generic_writepages() also! */ int mpage_writepages(struct address_space *mapping, -- cgit v1.2.3 From b71e8a4ce03b3098c7801ee5e6e08d1a39a226c2 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:11 +0100 Subject: [PATCH] BLOCK: Move __invalidate_device() to block_dev.c [try #6] Move __invalidate_device() from fs/inode.c to fs/block_dev.c so that it can more easily be disabled when the block layer is disabled. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/block_dev.c | 21 +++++++++++++++++++++ fs/inode.c | 21 --------------------- 2 files changed, 21 insertions(+), 21 deletions(-) (limited to 'fs') diff --git a/fs/block_dev.c b/fs/block_dev.c index 335c38bb86e..0c361ea7e5a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1315,3 +1315,24 @@ void close_bdev_excl(struct block_device *bdev) } EXPORT_SYMBOL(close_bdev_excl); + +int __invalidate_device(struct block_device *bdev) +{ + struct super_block *sb = get_super(bdev); + int res = 0; + + if (sb) { + /* + * no need to lock the super, get_super holds the + * read mutex so the filesystem cannot go away + * under us (->put_super runs with the write lock + * hold). + */ + shrink_dcache_sb(sb); + res = invalidate_inodes(sb); + drop_super(sb); + } + invalidate_bdev(bdev, 0); + return res; +} +EXPORT_SYMBOL(__invalidate_device); diff --git a/fs/inode.c b/fs/inode.c index abf77471e6c..ada7643104e 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -362,27 +362,6 @@ int invalidate_inodes(struct super_block * sb) } EXPORT_SYMBOL(invalidate_inodes); - -int __invalidate_device(struct block_device *bdev) -{ - struct super_block *sb = get_super(bdev); - int res = 0; - - if (sb) { - /* - * no need to lock the super, get_super holds the - * read mutex so the filesystem cannot go away - * under us (->put_super runs with the write lock - * hold). - */ - shrink_dcache_sb(sb); - res = invalidate_inodes(sb); - drop_super(sb); - } - invalidate_bdev(bdev, 0); - return res; -} -EXPORT_SYMBOL(__invalidate_device); static int can_unuse(struct inode *inode) { -- cgit v1.2.3 From 863d5b822c02d0e7215fb84ca79e9f8c3e35f04e Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:14 +0100 Subject: [PATCH] BLOCK: Move the loop device ioctl compat stuff to the loop driver [try #6] Move the loop device ioctl compat stuff from fs/compat_ioctl.c to the loop driver so that the loop header file doesn't need to be included. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/compat_ioctl.c | 68 ------------------------------------------------------- 1 file changed, 68 deletions(-) (limited to 'fs') diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index ab74c9bd55f..3b0cf7fbd95 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -1214,71 +1213,6 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar return err; } -struct loop_info32 { - compat_int_t lo_number; /* ioctl r/o */ - compat_dev_t lo_device; /* ioctl r/o */ - compat_ulong_t lo_inode; /* ioctl r/o */ - compat_dev_t lo_rdevice; /* ioctl r/o */ - compat_int_t lo_offset; - compat_int_t lo_encrypt_type; - compat_int_t lo_encrypt_key_size; /* ioctl w/o */ - compat_int_t lo_flags; /* ioctl r/o */ - char lo_name[LO_NAME_SIZE]; - unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ - compat_ulong_t lo_init[2]; - char reserved[4]; -}; - -static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - mm_segment_t old_fs = get_fs(); - struct loop_info l; - struct loop_info32 __user *ul; - int err = -EINVAL; - - ul = compat_ptr(arg); - switch(cmd) { - case LOOP_SET_STATUS: - err = get_user(l.lo_number, &ul->lo_number); - err |= __get_user(l.lo_device, &ul->lo_device); - err |= __get_user(l.lo_inode, &ul->lo_inode); - err |= __get_user(l.lo_rdevice, &ul->lo_rdevice); - err |= __copy_from_user(&l.lo_offset, &ul->lo_offset, - 8 + (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); - if (err) { - err = -EFAULT; - } else { - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&l); - set_fs (old_fs); - } - break; - case LOOP_GET_STATUS: - set_fs (KERNEL_DS); - err = sys_ioctl (fd, cmd, (unsigned long)&l); - set_fs (old_fs); - if (!err) { - err = put_user(l.lo_number, &ul->lo_number); - err |= __put_user(l.lo_device, &ul->lo_device); - err |= __put_user(l.lo_inode, &ul->lo_inode); - err |= __put_user(l.lo_rdevice, &ul->lo_rdevice); - err |= __copy_to_user(&ul->lo_offset, &l.lo_offset, - (unsigned long)l.lo_init - (unsigned long)&l.lo_offset); - if (err) - err = -EFAULT; - } - break; - default: { - static int count; - if (++count <= 20) - printk("%s: Unknown loop ioctl cmd, fd(%d) " - "cmd(%08x) arg(%08lx)\n", - __FUNCTION__, fd, cmd, arg); - } - } - return err; -} - #ifdef CONFIG_VT static int vt_check(struct file *file) @@ -2808,8 +2742,6 @@ HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans) HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans) -HANDLE_IOCTL(LOOP_SET_STATUS, loop_status) -HANDLE_IOCTL(LOOP_GET_STATUS, loop_status) #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout) #ifdef CONFIG_VT -- cgit v1.2.3 From 36695673b012096228ebdc1b39a6a5850daa474e Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:16 +0100 Subject: [PATCH] BLOCK: Move common FS-specific ioctls to linux/fs.h [try #6] Move common FS-specific ioctls from linux/ext2_fs.h to linux/fs.h as FS_IOC_* and FS_IOC32_* and have the users of them use those as a base. Also move the GETFLAGS/SETFLAGS flags to linux/fs.h as FS_*_FL macros, and then have the other users use them as a base. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/cifs/ioctl.c | 7 +++---- fs/compat_ioctl.c | 15 --------------- fs/hfsplus/hfsplus_fs.h | 8 ++------ fs/hfsplus/ioctl.c | 17 ++++++++--------- fs/jfs/ioctl.c | 15 +++++++-------- 5 files changed, 20 insertions(+), 42 deletions(-) (limited to 'fs') diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index b0ea6687ab5..e34c7db00f6 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -22,7 +22,6 @@ */ #include -#include #include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" @@ -74,7 +73,7 @@ int cifs_ioctl (struct inode * inode, struct file * filep, } break; #ifdef CONFIG_CIFS_POSIX - case EXT2_IOC_GETFLAGS: + case FS_IOC_GETFLAGS: if(CIFS_UNIX_EXTATTR_CAP & caps) { if (pSMBFile == NULL) break; @@ -82,12 +81,12 @@ int cifs_ioctl (struct inode * inode, struct file * filep, &ExtAttrBits, &ExtAttrMask); if(rc == 0) rc = put_user(ExtAttrBits & - EXT2_FL_USER_VISIBLE, + FS_FL_USER_VISIBLE, (int __user *)arg); } break; - case EXT2_IOC_SETFLAGS: + case FS_IOC_SETFLAGS: if(CIFS_UNIX_EXTATTR_CAP & caps) { if(get_user(ExtAttrBits,(int __user *)arg)) { rc = -EFAULT; diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 3b0cf7fbd95..bd9c4f49d4e 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -123,21 +123,6 @@ #include #include -/* Aiee. Someone does not find a difference between int and long */ -#define EXT2_IOC32_GETFLAGS _IOR('f', 1, int) -#define EXT2_IOC32_SETFLAGS _IOW('f', 2, int) -#define EXT3_IOC32_GETVERSION _IOR('f', 3, int) -#define EXT3_IOC32_SETVERSION _IOW('f', 4, int) -#define EXT3_IOC32_GETRSVSZ _IOR('f', 5, int) -#define EXT3_IOC32_SETRSVSZ _IOW('f', 6, int) -#define EXT3_IOC32_GROUP_EXTEND _IOW('f', 7, unsigned int) -#ifdef CONFIG_JBD_DEBUG -#define EXT3_IOC32_WAIT_FOR_READONLY _IOR('f', 99, int) -#endif - -#define EXT2_IOC32_GETVERSION _IOR('v', 1, int) -#define EXT2_IOC32_SETVERSION _IOW('v', 2, int) - static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *f) { diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 8a1ca5ef7ad..3915635b447 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -246,12 +246,8 @@ struct hfsplus_readdir_data { /* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support * chattr/lsattr */ -#define HFSPLUS_IOC_EXT2_GETFLAGS _IOR('f', 1, long) -#define HFSPLUS_IOC_EXT2_SETFLAGS _IOW('f', 2, long) - -#define EXT2_FLAG_IMMUTABLE 0x00000010 /* Immutable file */ -#define EXT2_FLAG_APPEND 0x00000020 /* writes to file may only append */ -#define EXT2_FLAG_NODUMP 0x00000040 /* do not dump file */ +#define HFSPLUS_IOC_EXT2_GETFLAGS FS_IOC_GETFLAGS +#define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS /* diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index 13cf848ac83..79fd10402ea 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c @@ -28,11 +28,11 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, case HFSPLUS_IOC_EXT2_GETFLAGS: flags = 0; if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_IMMUTABLE) - flags |= EXT2_FLAG_IMMUTABLE; /* EXT2_IMMUTABLE_FL */ + flags |= FS_IMMUTABLE_FL; /* EXT2_IMMUTABLE_FL */ if (HFSPLUS_I(inode).rootflags & HFSPLUS_FLG_APPEND) - flags |= EXT2_FLAG_APPEND; /* EXT2_APPEND_FL */ + flags |= FS_APPEND_FL; /* EXT2_APPEND_FL */ if (HFSPLUS_I(inode).userflags & HFSPLUS_FLG_NODUMP) - flags |= EXT2_FLAG_NODUMP; /* EXT2_NODUMP_FL */ + flags |= FS_NODUMP_FL; /* EXT2_NODUMP_FL */ return put_user(flags, (int __user *)arg); case HFSPLUS_IOC_EXT2_SETFLAGS: { if (IS_RDONLY(inode)) @@ -44,32 +44,31 @@ int hfsplus_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, if (get_user(flags, (int __user *)arg)) return -EFAULT; - if (flags & (EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND) || + if (flags & (FS_IMMUTABLE_FL|FS_APPEND_FL) || HFSPLUS_I(inode).rootflags & (HFSPLUS_FLG_IMMUTABLE|HFSPLUS_FLG_APPEND)) { if (!capable(CAP_LINUX_IMMUTABLE)) return -EPERM; } /* don't silently ignore unsupported ext2 flags */ - if (flags & ~(EXT2_FLAG_IMMUTABLE|EXT2_FLAG_APPEND| - EXT2_FLAG_NODUMP)) + if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) return -EOPNOTSUPP; - if (flags & EXT2_FLAG_IMMUTABLE) { /* EXT2_IMMUTABLE_FL */ + if (flags & FS_IMMUTABLE_FL) { /* EXT2_IMMUTABLE_FL */ inode->i_flags |= S_IMMUTABLE; HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_IMMUTABLE; } else { inode->i_flags &= ~S_IMMUTABLE; HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_IMMUTABLE; } - if (flags & EXT2_FLAG_APPEND) { /* EXT2_APPEND_FL */ + if (flags & FS_APPEND_FL) { /* EXT2_APPEND_FL */ inode->i_flags |= S_APPEND; HFSPLUS_I(inode).rootflags |= HFSPLUS_FLG_APPEND; } else { inode->i_flags &= ~S_APPEND; HFSPLUS_I(inode).rootflags &= ~HFSPLUS_FLG_APPEND; } - if (flags & EXT2_FLAG_NODUMP) /* EXT2_NODUMP_FL */ + if (flags & FS_NODUMP_FL) /* EXT2_NODUMP_FL */ HFSPLUS_I(inode).userflags |= HFSPLUS_FLG_NODUMP; else HFSPLUS_I(inode).userflags &= ~HFSPLUS_FLG_NODUMP; diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index 67b3774820e..37db5248826 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include @@ -22,13 +21,13 @@ static struct { long jfs_flag; long ext2_flag; } jfs_map[] = { - {JFS_NOATIME_FL, EXT2_NOATIME_FL}, - {JFS_DIRSYNC_FL, EXT2_DIRSYNC_FL}, - {JFS_SYNC_FL, EXT2_SYNC_FL}, - {JFS_SECRM_FL, EXT2_SECRM_FL}, - {JFS_UNRM_FL, EXT2_UNRM_FL}, - {JFS_APPEND_FL, EXT2_APPEND_FL}, - {JFS_IMMUTABLE_FL, EXT2_IMMUTABLE_FL}, + {JFS_NOATIME_FL, FS_NOATIME_FL}, + {JFS_DIRSYNC_FL, FS_DIRSYNC_FL}, + {JFS_SYNC_FL, FS_SYNC_FL}, + {JFS_SECRM_FL, FS_SECRM_FL}, + {JFS_UNRM_FL, FS_UNRM_FL}, + {JFS_APPEND_FL, FS_APPEND_FL}, + {JFS_IMMUTABLE_FL, FS_IMMUTABLE_FL}, {0, 0}, }; -- cgit v1.2.3 From 52b499c438ff60991eb3855ca090782569b3e8cf Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:18 +0100 Subject: [PATCH] BLOCK: Move the ReiserFS device ioctl compat stuff to the ReiserFS driver [try #6] Move the ReiserFS device ioctl compat stuff from fs/compat_ioctl.c to the ReiserFS driver so that the ReiserFS header file doesn't need to be included. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/compat_ioctl.c | 12 ------------ fs/reiserfs/dir.c | 3 +++ fs/reiserfs/file.c | 4 ++++ fs/reiserfs/ioctl.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 12 deletions(-) (limited to 'fs') diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index bd9c4f49d4e..0346f2ab57c 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -59,7 +59,6 @@ #include #include #include -#include #include #include #include @@ -2014,16 +2013,6 @@ static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg) return ret; } -#define REISERFS_IOC_UNPACK32 _IOW(0xCD,1,int) - -static int reiserfs_ioctl32(unsigned fd, unsigned cmd, unsigned long ptr) -{ - if (cmd == REISERFS_IOC_UNPACK32) - cmd = REISERFS_IOC_UNPACK; - - return sys_ioctl(fd,cmd,ptr); -} - struct raw32_config_request { compat_int_t raw_minor; @@ -2784,7 +2773,6 @@ HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64) /* vfat */ HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32) HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32) -HANDLE_IOCTL(REISERFS_IOC_UNPACK32, reiserfs_ioctl32) /* Raw devices */ HANDLE_IOCTL(RAW_SETBIND, raw_ioctl) HANDLE_IOCTL(RAW_GETBIND, raw_ioctl) diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 9aabcc0ccd2..657050ad743 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -22,6 +22,9 @@ const struct file_operations reiserfs_dir_operations = { .readdir = reiserfs_readdir, .fsync = reiserfs_dir_fsync, .ioctl = reiserfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = reiserfs_compat_ioctl, +#endif }; static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 1cfbe857ba2..3e08f7161a3 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -2,6 +2,7 @@ * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README */ +#include #include #include #include @@ -1568,6 +1569,9 @@ const struct file_operations reiserfs_file_operations = { .read = generic_file_read, .write = reiserfs_file_write, .ioctl = reiserfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = reiserfs_compat_ioctl, +#endif .mmap = generic_file_mmap, .release = reiserfs_file_release, .fsync = reiserfs_sync_file, diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index a986b5e1e28..9c57578cb83 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -9,6 +9,7 @@ #include #include #include +#include static int reiserfs_unpack(struct inode *inode, struct file *filp); @@ -94,6 +95,40 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, } } +#ifdef CONFIG_COMPAT +long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct inode *inode = file->f_dentry->d_inode; + int ret; + + /* These are just misnamed, they actually get/put from/to user an int */ + switch (cmd) { + case REISERFS_IOC32_UNPACK: + cmd = REISERFS_IOC_UNPACK; + break; + case REISERFS_IOC32_GETFLAGS: + cmd = REISERFS_IOC_GETFLAGS; + break; + case REISERFS_IOC32_SETFLAGS: + cmd = REISERFS_IOC_SETFLAGS; + break; + case REISERFS_IOC32_GETVERSION: + cmd = REISERFS_IOC_GETVERSION; + break; + case REISERFS_IOC32_SETVERSION: + cmd = REISERFS_IOC_SETVERSION; + break; + default: + return -ENOIOCTLCMD; + } + lock_kernel(); + ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); + unlock_kernel(); + return ret; +} +#endif + /* ** reiserfs_unpack ** Function try to convert tail from direct item into indirect. -- cgit v1.2.3 From e322ff07fb2d0f05c02d85e7c6b30d23f308c20f Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:20 +0100 Subject: [PATCH] BLOCK: Move the Ext2 device ioctl compat stuff to the Ext2 driver [try #6] Move the Ext2 device ioctl compat stuff from fs/compat_ioctl.c to the Ext2 driver so that the Ext2 header file doesn't need to be included. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/compat_ioctl.c | 17 ----------------- fs/ext2/dir.c | 3 +++ fs/ext2/ext2.h | 1 + fs/ext2/file.c | 6 ++++++ fs/ext2/ioctl.c | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 17 deletions(-) (limited to 'fs') diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 0346f2ab57c..3594668559a 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -159,18 +158,6 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) return err; } -static int do_ext2_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - /* These are just misnamed, they actually get/put from/to user an int */ - switch (cmd) { - case EXT2_IOC32_GETFLAGS: cmd = EXT2_IOC_GETFLAGS; break; - case EXT2_IOC32_SETFLAGS: cmd = EXT2_IOC_SETFLAGS; break; - case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break; - case EXT2_IOC32_SETVERSION: cmd = EXT2_IOC_SETVERSION; break; - } - return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); -} - static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) { /* These are just misnamed, they actually get/put from/to user an int */ @@ -2725,10 +2712,6 @@ HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl) HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl) HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl) #endif -HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl) -HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl) HANDLE_IOCTL(EXT3_IOC32_GETVERSION, do_ext3_ioctl) HANDLE_IOCTL(EXT3_IOC32_SETVERSION, do_ext3_ioctl) HANDLE_IOCTL(EXT3_IOC32_GETRSVSZ, do_ext3_ioctl) diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 92ea8265d7d..3e7a84a1e50 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -661,5 +661,8 @@ const struct file_operations ext2_dir_operations = { .read = generic_read_dir, .readdir = ext2_readdir, .ioctl = ext2_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext2_compat_ioctl, +#endif .fsync = ext2_sync_file, }; diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index e65a019fc7a..c19ac153f56 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -137,6 +137,7 @@ extern void ext2_set_inode_flags(struct inode *inode); /* ioctl.c */ extern int ext2_ioctl (struct inode *, struct file *, unsigned int, unsigned long); +extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long); /* namei.c */ struct dentry *ext2_get_parent(struct dentry *child); diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 23e2c7ccec1..e8bbed9dd26 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -46,6 +46,9 @@ const struct file_operations ext2_file_operations = { .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .ioctl = ext2_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext2_compat_ioctl, +#endif .mmap = generic_file_mmap, .open = generic_file_open, .release = ext2_release_file, @@ -63,6 +66,9 @@ const struct file_operations ext2_xip_file_operations = { .read = xip_file_read, .write = xip_file_write, .ioctl = ext2_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext2_compat_ioctl, +#endif .mmap = xip_file_mmap, .open = generic_file_open, .release = ext2_release_file, diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 3ca9afdf713..1dfba77eab1 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include @@ -80,3 +82,33 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, return -ENOTTY; } } + +#ifdef CONFIG_COMPAT +long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file->f_dentry->d_inode; + int ret; + + /* These are just misnamed, they actually get/put from/to user an int */ + switch (cmd) { + case EXT2_IOC32_GETFLAGS: + cmd = EXT2_IOC_GETFLAGS; + break; + case EXT2_IOC32_SETFLAGS: + cmd = EXT2_IOC_SETFLAGS; + break; + case EXT2_IOC32_GETVERSION: + cmd = EXT2_IOC_GETVERSION; + break; + case EXT2_IOC32_SETVERSION: + cmd = EXT2_IOC_SETVERSION; + break; + default: + return -ENOIOCTLCMD; + } + lock_kernel(); + ret = ext2_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); + unlock_kernel(); + return ret; +} +#endif -- cgit v1.2.3 From 52a700c5675f399c07e6e57328291e57f13ef3bb Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:23 +0100 Subject: [PATCH] BLOCK: Move the Ext3 device ioctl compat stuff to the Ext3 driver [try #6] Move the Ext3 device ioctl compat stuff from fs/compat_ioctl.c to the Ext3 driver so that the Ext3 header file doesn't need to be included. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/compat_ioctl.c | 27 --------------------------- fs/ext3/dir.c | 3 +++ fs/ext3/file.c | 3 +++ fs/ext3/ioctl.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 28 deletions(-) (limited to 'fs') diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 3594668559a..e5eb0f10f05 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -45,8 +45,6 @@ #include #include #include -#include -#include #include #include #include @@ -158,22 +156,6 @@ static int rw_long(unsigned int fd, unsigned int cmd, unsigned long arg) return err; } -static int do_ext3_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - /* These are just misnamed, they actually get/put from/to user an int */ - switch (cmd) { - case EXT3_IOC32_GETVERSION: cmd = EXT3_IOC_GETVERSION; break; - case EXT3_IOC32_SETVERSION: cmd = EXT3_IOC_SETVERSION; break; - case EXT3_IOC32_GETRSVSZ: cmd = EXT3_IOC_GETRSVSZ; break; - case EXT3_IOC32_SETRSVSZ: cmd = EXT3_IOC_SETRSVSZ; break; - case EXT3_IOC32_GROUP_EXTEND: cmd = EXT3_IOC_GROUP_EXTEND; break; -#ifdef CONFIG_JBD_DEBUG - case EXT3_IOC32_WAIT_FOR_READONLY: cmd = EXT3_IOC_WAIT_FOR_READONLY; break; -#endif - } - return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg)); -} - struct compat_video_event { int32_t type; compat_time_t timestamp; @@ -2712,15 +2694,6 @@ HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl) HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl) HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl) #endif -HANDLE_IOCTL(EXT3_IOC32_GETVERSION, do_ext3_ioctl) -HANDLE_IOCTL(EXT3_IOC32_SETVERSION, do_ext3_ioctl) -HANDLE_IOCTL(EXT3_IOC32_GETRSVSZ, do_ext3_ioctl) -HANDLE_IOCTL(EXT3_IOC32_SETRSVSZ, do_ext3_ioctl) -HANDLE_IOCTL(EXT3_IOC32_GROUP_EXTEND, do_ext3_ioctl) -COMPATIBLE_IOCTL(EXT3_IOC_GROUP_ADD) -#ifdef CONFIG_JBD_DEBUG -HANDLE_IOCTL(EXT3_IOC32_WAIT_FOR_READONLY, do_ext3_ioctl) -#endif /* One SMB ioctl needs translations. */ #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid) diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 429acbb4e06..d0b54f30b91 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c @@ -44,6 +44,9 @@ const struct file_operations ext3_dir_operations = { .read = generic_read_dir, .readdir = ext3_readdir, /* we take BKL. needed?*/ .ioctl = ext3_ioctl, /* BKL held */ +#ifdef CONFIG_COMPAT + .compat_ioctl = ext3_compat_ioctl, +#endif .fsync = ext3_sync_file, /* BKL held */ #ifdef CONFIG_EXT3_INDEX .release = ext3_release_dir, diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 994efd189f4..74ff20f9d09 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -114,6 +114,9 @@ const struct file_operations ext3_file_operations = { .readv = generic_file_readv, .writev = generic_file_writev, .ioctl = ext3_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ext3_compat_ioctl, +#endif .mmap = generic_file_mmap, .open = generic_file_open, .release = ext3_release_file, diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 3a6b012d120..12daa686957 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c @@ -13,9 +13,10 @@ #include #include #include +#include +#include #include - int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long arg) { @@ -252,3 +253,55 @@ flags_err: return -ENOTTY; } } + +#ifdef CONFIG_COMPAT +long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file->f_dentry->d_inode; + int ret; + + /* These are just misnamed, they actually get/put from/to user an int */ + switch (cmd) { + case EXT3_IOC32_GETFLAGS: + cmd = EXT3_IOC_GETFLAGS; + break; + case EXT3_IOC32_SETFLAGS: + cmd = EXT3_IOC_SETFLAGS; + break; + case EXT3_IOC32_GETVERSION: + cmd = EXT3_IOC_GETVERSION; + break; + case EXT3_IOC32_SETVERSION: + cmd = EXT3_IOC_SETVERSION; + break; + case EXT3_IOC32_GROUP_EXTEND: + cmd = EXT3_IOC_GROUP_EXTEND; + break; + case EXT3_IOC32_GETVERSION_OLD: + cmd = EXT3_IOC_GETVERSION_OLD; + break; + case EXT3_IOC32_SETVERSION_OLD: + cmd = EXT3_IOC_SETVERSION_OLD; + break; +#ifdef CONFIG_JBD_DEBUG + case EXT3_IOC32_WAIT_FOR_READONLY: + cmd = EXT3_IOC_WAIT_FOR_READONLY; + break; +#endif + case EXT3_IOC32_GETRSVSZ: + cmd = EXT3_IOC_GETRSVSZ; + break; + case EXT3_IOC32_SETRSVSZ: + cmd = EXT3_IOC_SETRSVSZ; + break; + case EXT3_IOC_GROUP_ADD: + break; + default: + return -ENOIOCTLCMD; + } + lock_kernel(); + ret = ext3_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); + unlock_kernel(); + return ret; +} +#endif -- cgit v1.2.3 From 188f83dfe0eeecd1427d0d255cc97dbf7ef6b4b7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 31 Aug 2006 12:50:04 +0200 Subject: [PATCH] BLOCK: Move the msdos device ioctl compat stuff to the msdos driver [try #6] Move the msdos device ioctl compat stuff from fs/compat_ioctl.c to the msdos driver so that the msdos header file doesn't need to be included. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/compat_ioctl.c | 49 ------------------------------------------------ fs/fat/dir.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 49 deletions(-) (limited to 'fs') diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index e5eb0f10f05..e1a56437040 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -108,7 +108,6 @@ #include #include #include -#include #include #include @@ -1937,51 +1936,6 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg) return err; } -#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) -#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) - -static long -put_dirent32 (struct dirent *d, struct compat_dirent __user *d32) -{ - if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent))) - return -EFAULT; - - __put_user(d->d_ino, &d32->d_ino); - __put_user(d->d_off, &d32->d_off); - __put_user(d->d_reclen, &d32->d_reclen); - if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen)) - return -EFAULT; - - return 0; -} - -static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg) -{ - struct compat_dirent __user *p = compat_ptr(arg); - int ret; - mm_segment_t oldfs = get_fs(); - struct dirent d[2]; - - switch(cmd) - { - case VFAT_IOCTL_READDIR_BOTH32: - cmd = VFAT_IOCTL_READDIR_BOTH; - break; - case VFAT_IOCTL_READDIR_SHORT32: - cmd = VFAT_IOCTL_READDIR_SHORT; - break; - } - - set_fs(KERNEL_DS); - ret = sys_ioctl(fd,cmd,(unsigned long)&d); - set_fs(oldfs); - if (ret >= 0) { - ret |= put_dirent32(&d[0], p); - ret |= put_dirent32(&d[1], p + 1); - } - return ret; -} - struct raw32_config_request { compat_int_t raw_minor; @@ -2726,9 +2680,6 @@ HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl) HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget) HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset) HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64) -/* vfat */ -HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32) -HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32) /* Raw devices */ HANDLE_IOCTL(RAW_SETBIND, raw_ioctl) HANDLE_IOCTL(RAW_GETBIND, raw_ioctl) diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 698b85bb1dd..3e50a416628 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -20,6 +20,7 @@ #include #include #include +#include #include static inline loff_t fat_make_i_pos(struct super_block *sb, @@ -741,10 +742,65 @@ static int fat_dir_ioctl(struct inode * inode, struct file * filp, return ret; } +#ifdef CONFIG_COMPAT +#define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) +#define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) + +static long fat_compat_put_dirent32(struct dirent *d, + struct compat_dirent __user *d32) +{ + if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent))) + return -EFAULT; + + __put_user(d->d_ino, &d32->d_ino); + __put_user(d->d_off, &d32->d_off); + __put_user(d->d_reclen, &d32->d_reclen); + if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen)) + return -EFAULT; + + return 0; +} + +static long fat_compat_dir_ioctl(struct file *file, unsigned cmd, + unsigned long arg) +{ + struct compat_dirent __user *p = compat_ptr(arg); + int ret; + mm_segment_t oldfs = get_fs(); + struct dirent d[2]; + + switch (cmd) { + case VFAT_IOCTL_READDIR_BOTH32: + cmd = VFAT_IOCTL_READDIR_BOTH; + break; + case VFAT_IOCTL_READDIR_SHORT32: + cmd = VFAT_IOCTL_READDIR_SHORT; + break; + default: + return -ENOIOCTLCMD; + } + + set_fs(KERNEL_DS); + lock_kernel(); + ret = fat_dir_ioctl(file->f_dentry->d_inode, file, + cmd, (unsigned long) &d); + unlock_kernel(); + set_fs(oldfs); + if (ret >= 0) { + ret |= fat_compat_put_dirent32(&d[0], p); + ret |= fat_compat_put_dirent32(&d[1], p + 1); + } + return ret; +} +#endif /* CONFIG_COMPAT */ + const struct file_operations fat_dir_operations = { .read = generic_read_dir, .readdir = fat_readdir, .ioctl = fat_dir_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = fat_compat_dir_ioctl, +#endif .fsync = file_fsync, }; -- cgit v1.2.3 From 4cb50dc2eaeddb0bc20bc4cd108c4fec99f5045a Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:27 +0100 Subject: [PATCH] BLOCK: Remove no-longer necessary linux/mpage.h inclusions [try #6] Remove inclusions of linux/mpage.h that are no longer necessary due to the transfer of generic_writepages(). Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/cifs/file.c | 1 - fs/nfs/write.c | 1 - 2 files changed, 2 deletions(-) (limited to 'fs') diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ddb012a6802..976a691c5a6 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/fs/nfs/write.c b/fs/nfs/write.c index b674462793d..f6675d2c386 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From d366e40a1cabd453be6e2609caa7e12f9ca17b1f Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 29 Aug 2006 19:06:29 +0100 Subject: [PATCH] BLOCK: Remove no-longer necessary linux/buffer_head.h inclusions [try #6] Remove inclusions of linux/buffer_head.h that are no longer necessary due to the transfer of a number of things out of there. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/afs/file.c | 1 - fs/cifs/inode.c | 1 - 2 files changed, 2 deletions(-) (limited to 'fs') diff --git a/fs/afs/file.c b/fs/afs/file.c index 02264560d17..2e8c42639ea 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "volume.h" #include "vnode.h" #include diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b88147c1dc2..05f874c7441 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -19,7 +19,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include #include #include #include -- cgit v1.2.3 From 9361401eb7619c033e2394e4f9f6d410d6719ac7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Sat, 30 Sep 2006 20:45:40 +0200 Subject: [PATCH] BLOCK: Make it possible to disable the block layer [try #6] Make it possible to disable the block layer. Not all embedded devices require it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require the block layer to be present. This patch does the following: (*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev support. (*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls an item that uses the block layer. This includes: (*) Block I/O tracing. (*) Disk partition code. (*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS. (*) The SCSI layer. As far as I can tell, even SCSI chardevs use the block layer to do scheduling. Some drivers that use SCSI facilities - such as USB storage - end up disabled indirectly from this. (*) Various block-based device drivers, such as IDE and the old CDROM drivers. (*) MTD blockdev handling and FTL. (*) JFFS - which uses set_bdev_super(), something it could avoid doing by taking a leaf out of JFFS2's book. (*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and linux/elevator.h contingent on CONFIG_BLOCK being set. sector_div() is, however, still used in places, and so is still available. (*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and parts of linux/fs.h. (*) Makes a number of files in fs/ contingent on CONFIG_BLOCK. (*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK. (*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK is not enabled. (*) fs/no-block.c is created to hold out-of-line stubs and things that are required when CONFIG_BLOCK is not set: (*) Default blockdev file operations (to give error ENODEV on opening). (*) Makes some /proc changes: (*) /proc/devices does not list any blockdevs. (*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK. (*) Makes some compat ioctl handling contingent on CONFIG_BLOCK. (*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if given command other than Q_SYNC or if a special device is specified. (*) In init/do_mounts.c, no reference is made to the blockdev routines if CONFIG_BLOCK is not defined. This does not prohibit NFS roots or JFFS2. (*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return error ENOSYS by way of cond_syscall if so). (*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if CONFIG_BLOCK is not set, since they can't then happen. Signed-Off-By: David Howells Signed-off-by: Jens Axboe --- fs/Kconfig | 31 ++++++++++++++++++++++++------- fs/Makefile | 14 ++++++++++---- fs/compat_ioctl.c | 18 ++++++++++++++++++ fs/internal.h | 6 ++++++ fs/no-block.c | 22 ++++++++++++++++++++++ fs/partitions/Makefile | 2 +- fs/proc/proc_misc.c | 11 ++++++++++- fs/quota.c | 44 +++++++++++++++++++++++++++++++------------- fs/super.c | 4 ++++ fs/xfs/Kconfig | 1 + 10 files changed, 127 insertions(+), 26 deletions(-) create mode 100644 fs/no-block.c (limited to 'fs') diff --git a/fs/Kconfig b/fs/Kconfig index 4fd9efac29a..1453d2d164f 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -4,6 +4,8 @@ menu "File systems" +if BLOCK + config EXT2_FS tristate "Second extended fs support" help @@ -399,6 +401,8 @@ config ROMFS_FS If you don't know whether you need it, then you don't need it: answer N. +endif + config INOTIFY bool "Inotify file change notification support" default y @@ -530,6 +534,7 @@ config FUSE_FS If you want to develop a userspace FS, or if you want to use a filesystem based on FUSE, answer Y or M. +if BLOCK menu "CD-ROM/DVD Filesystems" config ISO9660_FS @@ -597,7 +602,9 @@ config UDF_NLS depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y) endmenu +endif +if BLOCK menu "DOS/FAT/NT Filesystems" config FAT_FS @@ -782,6 +789,7 @@ config NTFS_RW It is perfectly safe to say N here. endmenu +endif menu "Pseudo filesystems" @@ -939,7 +947,7 @@ menu "Miscellaneous filesystems" config ADFS_FS tristate "ADFS file system support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL help The Acorn Disc Filing System is the standard file system of the RiscOS operating system which runs on Acorn's ARM-based Risc PC @@ -967,7 +975,7 @@ config ADFS_FS_RW config AFFS_FS tristate "Amiga FFS file system support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL help The Fast File System (FFS) is the common file system used on hard disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20). Say Y @@ -989,7 +997,7 @@ config AFFS_FS config HFS_FS tristate "Apple Macintosh file system support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL select NLS help If you say Y here, you will be able to mount Macintosh-formatted @@ -1002,6 +1010,7 @@ config HFS_FS config HFSPLUS_FS tristate "Apple Extended HFS file system support" + depends on BLOCK select NLS select NLS_UTF8 help @@ -1015,7 +1024,7 @@ config HFSPLUS_FS config BEFS_FS tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL select NLS help The BeOS File System (BeFS) is the native file system of Be, Inc's @@ -1042,7 +1051,7 @@ config BEFS_DEBUG config BFS_FS tristate "BFS file system support (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL help Boot File System (BFS) is a file system used under SCO UnixWare to allow the bootloader access to the kernel image and other important @@ -1064,7 +1073,7 @@ config BFS_FS config EFS_FS tristate "EFS file system support (read only) (EXPERIMENTAL)" - depends on EXPERIMENTAL + depends on BLOCK && EXPERIMENTAL help EFS is an older file system used for non-ISO9660 CD-ROMs and hard disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer @@ -1079,7 +1088,7 @@ config EFS_FS config JFFS_FS tristate "Journalling Flash File System (JFFS) support" - depends on MTD + depends on MTD && BLOCK help JFFS is the Journaling Flash File System developed by Axis Communications in Sweden, aimed at providing a crash/powerdown-safe @@ -1264,6 +1273,7 @@ endchoice config CRAMFS tristate "Compressed ROM file system support (cramfs)" + depends on BLOCK select ZLIB_INFLATE help Saying Y here includes support for CramFs (Compressed ROM File @@ -1283,6 +1293,7 @@ config CRAMFS config VXFS_FS tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" + depends on BLOCK help FreeVxFS is a file system driver that support the VERITAS VxFS(TM) file system format. VERITAS VxFS(TM) is the standard file system @@ -1300,6 +1311,7 @@ config VXFS_FS config HPFS_FS tristate "OS/2 HPFS file system support" + depends on BLOCK help OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS is the file system used for organizing files on OS/2 hard disk @@ -1316,6 +1328,7 @@ config HPFS_FS config QNX4FS_FS tristate "QNX4 file system support (read only)" + depends on BLOCK help This is the file system used by the real-time operating systems QNX 4 and QNX 6 (the latter is also called QNX RTP). @@ -1343,6 +1356,7 @@ config QNX4FS_RW config SYSV_FS tristate "System V/Xenix/V7/Coherent file system support" + depends on BLOCK help SCO, Xenix and Coherent are commercial Unix systems for Intel machines, and Version 7 was used on the DEC PDP-11. Saying Y @@ -1381,6 +1395,7 @@ config SYSV_FS config UFS_FS tristate "UFS file system support (read only)" + depends on BLOCK help BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD, OpenBSD and NeXTstep) use a file system called UFS. Some System V @@ -1959,11 +1974,13 @@ config GENERIC_ACL endmenu +if BLOCK menu "Partition Types" source "fs/partitions/Kconfig" endmenu +endif source "fs/nls/Kconfig" diff --git a/fs/Makefile b/fs/Makefile index 46b8cfe497b..a503e6ce0f3 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -5,12 +5,18 @@ # Rewritten to use lists instead of if-statements. # -obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \ - block_dev.o char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ +obj-y := open.o read_write.o file_table.o super.o \ + char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \ ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ - seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \ - ioprio.o pnode.o drop_caches.o splice.o sync.o + seq_file.o xattr.o libfs.o fs-writeback.o \ + pnode.o drop_caches.o splice.o sync.o + +ifeq ($(CONFIG_BLOCK),y) +obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o +else +obj-y += no-block.o +endif obj-$(CONFIG_INOTIFY) += inotify.o obj-$(CONFIG_INOTIFY_USER) += inotify_user.o diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index e1a56437040..64b34533ede 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -645,6 +645,7 @@ out: } #endif +#ifdef CONFIG_BLOCK struct hd_geometry32 { unsigned char heads; unsigned char sectors; @@ -869,6 +870,7 @@ static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) } return err; } +#endif /* CONFIG_BLOCK */ struct sock_fprog32 { unsigned short len; @@ -992,6 +994,7 @@ static int ppp_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg) } +#ifdef CONFIG_BLOCK struct mtget32 { compat_long_t mt_type; compat_long_t mt_resid; @@ -1164,6 +1167,7 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar return err; } +#endif /* CONFIG_BLOCK */ #ifdef CONFIG_VT @@ -1491,6 +1495,7 @@ ret_einval(unsigned int fd, unsigned int cmd, unsigned long arg) return -EINVAL; } +#ifdef CONFIG_BLOCK static int broken_blkgetsize(unsigned int fd, unsigned int cmd, unsigned long arg) { /* The mkswap binary hard codes it to Intel value :-((( */ @@ -1525,12 +1530,14 @@ static int blkpg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar return sys_ioctl(fd, cmd, (unsigned long)a); } +#endif static int ioc_settimeout(unsigned int fd, unsigned int cmd, unsigned long arg) { return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); } +#ifdef CONFIG_BLOCK /* Fix sizeof(sizeof()) breakage */ #define BLKBSZGET_32 _IOR(0x12,112,int) #define BLKBSZSET_32 _IOW(0x12,113,int) @@ -1551,6 +1558,7 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd, { return sys_ioctl(fd, BLKGETSIZE64, (unsigned long)compat_ptr(arg)); } +#endif /* Bluetooth ioctls */ #define HCIUARTSETPROTO _IOW('U', 200, int) @@ -1571,6 +1579,7 @@ static int do_blkgetsize64(unsigned int fd, unsigned int cmd, #define HIDPGETCONNLIST _IOR('H', 210, int) #define HIDPGETCONNINFO _IOR('H', 211, int) +#ifdef CONFIG_BLOCK struct floppy_struct32 { compat_uint_t size; compat_uint_t sect; @@ -1895,6 +1904,7 @@ out: kfree(karg); return err; } +#endif struct mtd_oob_buf32 { u_int32_t start; @@ -1936,6 +1946,7 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg) return err; } +#ifdef CONFIG_BLOCK struct raw32_config_request { compat_int_t raw_minor; @@ -2000,6 +2011,7 @@ static int raw_ioctl(unsigned fd, unsigned cmd, unsigned long arg) } return ret; } +#endif /* CONFIG_BLOCK */ struct serial_struct32 { compat_int_t type; @@ -2606,6 +2618,7 @@ HANDLE_IOCTL(SIOCBRDELIF, dev_ifsioc) HANDLE_IOCTL(SIOCRTMSG, ret_einval) HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp) #endif +#ifdef CONFIG_BLOCK HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo) HANDLE_IOCTL(BLKRAGET, w_long) HANDLE_IOCTL(BLKGETSIZE, w_long) @@ -2631,14 +2644,17 @@ HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans) HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans) HANDLE_IOCTL(SG_IO,sg_ioctl_trans) HANDLE_IOCTL(SG_GET_REQUEST_TABLE, sg_grt_trans) +#endif HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans) HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans) HANDLE_IOCTL(PPPIOCSPASS32, ppp_sock_fprog_ioctl_trans) HANDLE_IOCTL(PPPIOCSACTIVE32, ppp_sock_fprog_ioctl_trans) +#ifdef CONFIG_BLOCK HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans) HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans) +#endif #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout) #ifdef CONFIG_VT @@ -2677,12 +2693,14 @@ HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl) HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl) HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl) /* block stuff */ +#ifdef CONFIG_BLOCK HANDLE_IOCTL(BLKBSZGET_32, do_blkbszget) HANDLE_IOCTL(BLKBSZSET_32, do_blkbszset) HANDLE_IOCTL(BLKGETSIZE64_32, do_blkgetsize64) /* Raw devices */ HANDLE_IOCTL(RAW_SETBIND, raw_ioctl) HANDLE_IOCTL(RAW_GETBIND, raw_ioctl) +#endif /* Serial */ HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl) HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl) diff --git a/fs/internal.h b/fs/internal.h index f662b703bb9..f07147d6325 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -14,10 +14,16 @@ /* * block_dev.c */ +#ifdef CONFIG_BLOCK extern struct super_block *blockdev_superblock; extern void __init bdev_cache_init(void); #define sb_is_blkdev_sb(sb) ((sb) == blockdev_superblock) +#else +static inline void bdev_cache_init(void) {} + +#define sb_is_blkdev_sb(sb) 0 +#endif /* * char_dev.c diff --git a/fs/no-block.c b/fs/no-block.c new file mode 100644 index 00000000000..d269a93d346 --- /dev/null +++ b/fs/no-block.c @@ -0,0 +1,22 @@ +/* no-block.c: implementation of routines required for non-BLOCK configuration + * + * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include + +static int no_blkdev_open(struct inode * inode, struct file * filp) +{ + return -ENODEV; +} + +const struct file_operations def_blk_fops = { + .open = no_blkdev_open, +}; diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile index d713ce6b3e1..67e665fdb7f 100644 --- a/fs/partitions/Makefile +++ b/fs/partitions/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := check.o +obj-$(CONFIG_BLOCK) := check.o obj-$(CONFIG_ACORN_PARTITION) += acorn.o obj-$(CONFIG_AMIGA_PARTITION) += amiga.o diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 5bbd6089605..66bc425f2f3 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c @@ -277,12 +277,15 @@ static int devinfo_show(struct seq_file *f, void *v) if (i == 0) seq_printf(f, "Character devices:\n"); chrdev_show(f, i); - } else { + } +#ifdef CONFIG_BLOCK + else { i -= CHRDEV_MAJOR_HASH_SIZE; if (i == 0) seq_printf(f, "\nBlock devices:\n"); blkdev_show(f, i); } +#endif return 0; } @@ -355,6 +358,7 @@ static int stram_read_proc(char *page, char **start, off_t off, } #endif +#ifdef CONFIG_BLOCK extern struct seq_operations partitions_op; static int partitions_open(struct inode *inode, struct file *file) { @@ -378,6 +382,7 @@ static struct file_operations proc_diskstats_operations = { .llseek = seq_lseek, .release = seq_release, }; +#endif #ifdef CONFIG_MODULES extern struct seq_operations modules_op; @@ -695,7 +700,9 @@ void __init proc_misc_init(void) entry->proc_fops = &proc_kmsg_operations; create_seq_entry("devices", 0, &proc_devinfo_operations); create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); +#ifdef CONFIG_BLOCK create_seq_entry("partitions", 0, &proc_partitions_operations); +#endif create_seq_entry("stat", 0, &proc_stat_operations); create_seq_entry("interrupts", 0, &proc_interrupts_operations); #ifdef CONFIG_SLAB @@ -707,7 +714,9 @@ void __init proc_misc_init(void) create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); +#ifdef CONFIG_BLOCK create_seq_entry("diskstats", 0, &proc_diskstats_operations); +#endif #ifdef CONFIG_MODULES create_seq_entry("modules", 0, &proc_modules_operations); #endif diff --git a/fs/quota.c b/fs/quota.c index d6a2be826e2..b9dae76a0b6 100644 --- a/fs/quota.c +++ b/fs/quota.c @@ -337,6 +337,34 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void return 0; } +/* + * look up a superblock on which quota ops will be performed + * - use the name of a block device to find the superblock thereon + */ +static inline struct super_block *quotactl_block(const char __user *special) +{ +#ifdef CONFIG_BLOCK + struct block_device *bdev; + struct super_block *sb; + char *tmp = getname(special); + + if (IS_ERR(tmp)) + return ERR_PTR(PTR_ERR(tmp)); + bdev = lookup_bdev(tmp); + putname(tmp); + if (IS_ERR(bdev)) + return ERR_PTR(PTR_ERR(bdev)); + sb = get_super(bdev); + bdput(bdev); + if (!sb) + return ERR_PTR(-ENODEV); + + return sb; +#else + return ERR_PTR(-ENODEV); +#endif +} + /* * This is the system call interface. This communicates with * the user-level programs. Currently this only supports diskquota @@ -347,25 +375,15 @@ asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, qid_t { uint cmds, type; struct super_block *sb = NULL; - struct block_device *bdev; - char *tmp; int ret; cmds = cmd >> SUBCMDSHIFT; type = cmd & SUBCMDMASK; if (cmds != Q_SYNC || special) { - tmp = getname(special); - if (IS_ERR(tmp)) - return PTR_ERR(tmp); - bdev = lookup_bdev(tmp); - putname(tmp); - if (IS_ERR(bdev)) - return PTR_ERR(bdev); - sb = get_super(bdev); - bdput(bdev); - if (!sb) - return -ENODEV; + sb = quotactl_block(special); + if (IS_ERR(sb)) + return PTR_ERR(sb); } ret = check_quotactl_valid(sb, type, cmds, id); diff --git a/fs/super.c b/fs/super.c index 15671cd048b..aec99ddbe53 100644 --- a/fs/super.c +++ b/fs/super.c @@ -571,8 +571,10 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) { int retval; +#ifdef CONFIG_BLOCK if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) return -EACCES; +#endif if (flags & MS_RDONLY) acct_auto_close(sb); shrink_dcache_sb(sb); @@ -692,6 +694,7 @@ void kill_litter_super(struct super_block *sb) EXPORT_SYMBOL(kill_litter_super); +#ifdef CONFIG_BLOCK static int set_bdev_super(struct super_block *s, void *data) { s->s_bdev = data; @@ -787,6 +790,7 @@ void kill_block_super(struct super_block *sb) } EXPORT_SYMBOL(kill_block_super); +#endif int get_sb_nodev(struct file_system_type *fs_type, int flags, void *data, diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 26b364c9d62..35115bca036 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -1,5 +1,6 @@ config XFS_FS tristate "XFS filesystem support" + depends on BLOCK help XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can -- cgit v1.2.3 From 5e6d12b2c8be2cac099df6dcb8b26884f24d2621 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 31 Aug 2006 12:55:23 +0200 Subject: [PATCH] CONFIG_BLOCK internal.h cleanups - forward declare struct superblock - use inlines, not macros Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- fs/internal.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/internal.h b/fs/internal.h index f07147d6325..ea00126c9a5 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -11,6 +11,8 @@ #include +struct super_block; + /* * block_dev.c */ @@ -18,11 +20,20 @@ extern struct super_block *blockdev_superblock; extern void __init bdev_cache_init(void); -#define sb_is_blkdev_sb(sb) ((sb) == blockdev_superblock) +static inline int sb_is_blkdev_sb(struct super_block *sb) +{ + return sb == blockdev_superblock; +} + #else -static inline void bdev_cache_init(void) {} +static inline void bdev_cache_init(void) +{ +} -#define sb_is_blkdev_sb(sb) 0 +static inline int sb_is_blkdev_sb(struct super_block *sb) +{ + return 0; +} #endif /* -- cgit v1.2.3 From 50be345560f1ffdcb15cc0e146416b80529a2ef2 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Mon, 4 Sep 2006 15:37:57 +0200 Subject: [PATCH] fix creating zero sized bio mempools in low memory system In the very low memory systems is in the init_bio call scale parameter set to zero and it leads to creating zero sized mempool. This patch prevents pool_entries parameter become zero, so the created pool have at least 1 entry. Mempool with 0 entries lead to incorrect behaviour of mempool_free. (Alloc requests are not waken up and system stalls in mempool_alloc->ioschedule). Signed-off-by: Milan Broz Signed-off-by: Jens Axboe --- fs/bio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs') diff --git a/fs/bio.c b/fs/bio.c index 6a0b9ad8f8c..52de79c2994 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -1142,7 +1142,7 @@ static int biovec_create_pools(struct bio_set *bs, int pool_entries, int scale) struct biovec_slab *bp = bvec_slabs + i; mempool_t **bvp = bs->bvec_pools + i; - if (i >= scale) + if (pool_entries > 1 && i >= scale) pool_entries >>= 1; *bvp = mempool_create_slab_pool(pool_entries, bp->slab); -- cgit v1.2.3 From 0fe23479577124bd2687e6783e39fa0fa4c28005 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 4 Sep 2006 15:41:16 +0200 Subject: [PATCH] Update axboe@suse.de email address As people often look for the copyright in files to see who to mail, update the link to a neutral one. Signed-off-by: Jens Axboe --- fs/bio.c | 2 +- fs/ioprio.c | 2 +- fs/splice.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/bio.c b/fs/bio.c index 52de79c2994..8f93e939f21 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Jens Axboe + * Copyright (C) 2001 Jens Axboe * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/fs/ioprio.c b/fs/ioprio.c index 03dc4f269b7..6dc6721d9e8 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c @@ -1,7 +1,7 @@ /* * fs/ioprio.c * - * Copyright (C) 2004 Jens Axboe + * Copyright (C) 2004 Jens Axboe * * Helper functions for setting/querying io priorities of processes. The * system calls closely mimmick getpriority/setpriority, see the man page for diff --git a/fs/splice.c b/fs/splice.c index 684bca3d3a1..13e92dd19fb 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -12,7 +12,7 @@ * Jens to support splicing to files, network, direct splicing, etc and * fixing lots of bugs. * - * Copyright (C) 2005-2006 Jens Axboe + * Copyright (C) 2005-2006 Jens Axboe * Copyright (C) 2005-2006 Linus Torvalds * Copyright (C) 2006 Ingo Molnar * -- cgit v1.2.3 From c49c31115067bc7c9a51ffdc735a515151dfa3eb Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Sat, 30 Sep 2006 23:27:12 -0700 Subject: [PATCH] fs/ntfs: Conversion to generic boolean Conversion of booleans to: generic-boolean.patch (2006-08-23) Signed-off-by: Richard Knutsson Signed-off-by: Anton Altaparmakov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ntfs/aops.c | 30 ++++----- fs/ntfs/aops.h | 2 +- fs/ntfs/attrib.c | 54 ++++++++-------- fs/ntfs/attrib.h | 8 +-- fs/ntfs/bitmap.c | 8 +-- fs/ntfs/bitmap.h | 4 +- fs/ntfs/collate.h | 8 +-- fs/ntfs/compress.c | 4 +- fs/ntfs/file.c | 34 +++++----- fs/ntfs/index.c | 4 +- fs/ntfs/index.h | 12 ++-- fs/ntfs/inode.c | 10 +-- fs/ntfs/layout.h | 6 +- fs/ntfs/lcnalloc.c | 20 +++--- fs/ntfs/lcnalloc.h | 8 +-- fs/ntfs/logfile.c | 108 ++++++++++++++++---------------- fs/ntfs/logfile.h | 6 +- fs/ntfs/mft.c | 58 ++++++++--------- fs/ntfs/mft.h | 2 +- fs/ntfs/ntfs.h | 2 +- fs/ntfs/quota.c | 12 ++-- fs/ntfs/quota.h | 2 +- fs/ntfs/runlist.c | 54 ++++++++-------- fs/ntfs/super.c | 178 ++++++++++++++++++++++++++--------------------------- fs/ntfs/types.h | 5 -- fs/ntfs/unistr.c | 8 +-- fs/ntfs/usnjrnl.c | 8 +-- fs/ntfs/usnjrnl.h | 2 +- 28 files changed, 326 insertions(+), 331 deletions(-) (limited to 'fs') diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index bc579bfdfbd..7b2c8f4f6a6 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c @@ -254,7 +254,7 @@ static int ntfs_read_block(struct page *page) bh->b_bdev = vol->sb->s_bdev; /* Is the block within the allowed limits? */ if (iblock < lblock) { - BOOL is_retry = FALSE; + bool is_retry = false; /* Convert iblock into corresponding vcn and offset. */ vcn = (VCN)iblock << blocksize_bits >> @@ -292,7 +292,7 @@ lock_retry_remap: goto handle_hole; /* If first try and runlist unmapped, map and retry. */ if (!is_retry && lcn == LCN_RL_NOT_MAPPED) { - is_retry = TRUE; + is_retry = true; /* * Attempt to map runlist, dropping lock for * the duration. @@ -558,7 +558,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc) unsigned long flags; unsigned int blocksize, vcn_ofs; int err; - BOOL need_end_writeback; + bool need_end_writeback; unsigned char blocksize_bits; vi = page->mapping->host; @@ -626,7 +626,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc) rl = NULL; err = 0; do { - BOOL is_retry = FALSE; + bool is_retry = false; if (unlikely(block >= dblock)) { /* @@ -768,7 +768,7 @@ lock_retry_remap: } /* If first try and runlist unmapped, map and retry. */ if (!is_retry && lcn == LCN_RL_NOT_MAPPED) { - is_retry = TRUE; + is_retry = true; /* * Attempt to map runlist, dropping lock for * the duration. @@ -874,12 +874,12 @@ lock_retry_remap: set_page_writeback(page); /* Keeps try_to_free_buffers() away. */ /* Submit the prepared buffers for i/o. */ - need_end_writeback = TRUE; + need_end_writeback = true; do { struct buffer_head *next = bh->b_this_page; if (buffer_async_write(bh)) { submit_bh(WRITE, bh); - need_end_writeback = FALSE; + need_end_writeback = false; } bh = next; } while (bh != head); @@ -932,7 +932,7 @@ static int ntfs_write_mst_block(struct page *page, runlist_element *rl; int i, nr_locked_nis, nr_recs, nr_bhs, max_bhs, bhs_per_rec, err, err2; unsigned bh_size, rec_size_bits; - BOOL sync, is_mft, page_is_dirty, rec_is_dirty; + bool sync, is_mft, page_is_dirty, rec_is_dirty; unsigned char bh_size_bits; ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " @@ -975,10 +975,10 @@ static int ntfs_write_mst_block(struct page *page, rl = NULL; err = err2 = nr_bhs = nr_recs = nr_locked_nis = 0; - page_is_dirty = rec_is_dirty = FALSE; + page_is_dirty = rec_is_dirty = false; rec_start_bh = NULL; do { - BOOL is_retry = FALSE; + bool is_retry = false; if (likely(block < rec_block)) { if (unlikely(block >= dblock)) { @@ -1009,10 +1009,10 @@ static int ntfs_write_mst_block(struct page *page, } if (!buffer_dirty(bh)) { /* Clean records are not written out. */ - rec_is_dirty = FALSE; + rec_is_dirty = false; continue; } - rec_is_dirty = TRUE; + rec_is_dirty = true; rec_start_bh = bh; } /* Need to map the buffer if it is not mapped already. */ @@ -1053,7 +1053,7 @@ lock_retry_remap: */ if (!is_mft && !is_retry && lcn == LCN_RL_NOT_MAPPED) { - is_retry = TRUE; + is_retry = true; /* * Attempt to map runlist, dropping * lock for the duration. @@ -1063,7 +1063,7 @@ lock_retry_remap: if (likely(!err2)) goto lock_retry_remap; if (err2 == -ENOMEM) - page_is_dirty = TRUE; + page_is_dirty = true; lcn = err2; } else { err2 = -EIO; @@ -1145,7 +1145,7 @@ lock_retry_remap: * means we need to redirty the page before * returning. */ - page_is_dirty = TRUE; + page_is_dirty = true; /* * Remove the buffers in this mft record from * the list of buffers to write. diff --git a/fs/ntfs/aops.h b/fs/ntfs/aops.h index 325ce261a10..9393f4b1e29 100644 --- a/fs/ntfs/aops.h +++ b/fs/ntfs/aops.h @@ -80,7 +80,7 @@ static inline void ntfs_unmap_page(struct page *page) * * The unlocked and uptodate page is returned on success or an encoded error * on failure. Caller has to test for error using the IS_ERR() macro on the - * return value. If that evaluates to TRUE, the negative error code can be + * return value. If that evaluates to 'true', the negative error code can be * obtained using PTR_ERR() on the return value of ntfs_map_page(). */ static inline struct page *ntfs_map_page(struct address_space *mapping, diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 6708e1d68a9..9f08e851cfb 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -67,7 +67,7 @@ * the attribute has zero allocated size, i.e. there simply is no runlist. * * WARNING: If @ctx is supplied, regardless of whether success or failure is - * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx * is no longer valid, i.e. you need to either call * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. * In that case PTR_ERR(@ctx->mrec) will give you the error code for @@ -90,7 +90,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) runlist_element *rl; struct page *put_this_page = NULL; int err = 0; - BOOL ctx_is_temporary, ctx_needs_reset; + bool ctx_is_temporary, ctx_needs_reset; ntfs_attr_search_ctx old_ctx = { NULL, }; ntfs_debug("Mapping runlist part containing vcn 0x%llx.", @@ -100,7 +100,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) else base_ni = ni->ext.base_ntfs_ino; if (!ctx) { - ctx_is_temporary = ctx_needs_reset = TRUE; + ctx_is_temporary = ctx_needs_reset = true; m = map_mft_record(base_ni); if (IS_ERR(m)) return PTR_ERR(m); @@ -115,7 +115,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) BUG_ON(IS_ERR(ctx->mrec)); a = ctx->attr; BUG_ON(!a->non_resident); - ctx_is_temporary = FALSE; + ctx_is_temporary = false; end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn); read_lock_irqsave(&ni->size_lock, flags); allocated_size_vcn = ni->allocated_size >> @@ -136,7 +136,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) ni->name, ni->name_len) && sle64_to_cpu(a->data.non_resident.lowest_vcn) <= vcn && end_vcn >= vcn)) - ctx_needs_reset = FALSE; + ctx_needs_reset = false; else { /* Save the old search context. */ old_ctx = *ctx; @@ -158,7 +158,7 @@ int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, ntfs_attr_search_ctx *ctx) * needed attribute extent. */ ntfs_attr_reinit_search_ctx(ctx); - ctx_needs_reset = TRUE; + ctx_needs_reset = true; } } if (ctx_needs_reset) { @@ -336,16 +336,16 @@ int ntfs_map_runlist(ntfs_inode *ni, VCN vcn) * LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc). * * Locking: - The runlist must be locked on entry and is left locked on return. - * - If @write_locked is FALSE, i.e. the runlist is locked for reading, + * - If @write_locked is 'false', i.e. the runlist is locked for reading, * the lock may be dropped inside the function so you cannot rely on * the runlist still being the same when this function returns. */ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, - const BOOL write_locked) + const bool write_locked) { LCN lcn; unsigned long flags; - BOOL is_retry = FALSE; + bool is_retry = false; ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.", ni->mft_no, (unsigned long long)vcn, @@ -390,7 +390,7 @@ retry_remap: down_read(&ni->runlist.lock); } if (likely(!err)) { - is_retry = TRUE; + is_retry = true; goto retry_remap; } if (err == -ENOENT) @@ -449,7 +449,7 @@ retry_remap: * -EIO - Critical error (runlist/file is corrupt, i/o error, etc). * * WARNING: If @ctx is supplied, regardless of whether success or failure is - * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx * is no longer valid, i.e. you need to either call * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. * In that case PTR_ERR(@ctx->mrec) will give you the error code for @@ -469,7 +469,7 @@ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, unsigned long flags; runlist_element *rl; int err = 0; - BOOL is_retry = FALSE; + bool is_retry = false; ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.", ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out"); @@ -518,7 +518,7 @@ retry_remap: */ err = ntfs_map_runlist_nolock(ni, vcn, ctx); if (likely(!err)) { - is_retry = TRUE; + is_retry = true; goto retry_remap; } } @@ -558,8 +558,8 @@ retry_remap: * On actual error, ntfs_attr_find() returns -EIO. In this case @ctx->attr is * undefined and in particular do not rely on it not changing. * - * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it - * is FALSE, the search begins after @ctx->attr. + * If @ctx->is_first is 'true', the search begins with @ctx->attr itself. If it + * is 'false', the search begins after @ctx->attr. * * If @ic is IGNORE_CASE, the @name comparisson is not case sensitive and * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record @@ -599,11 +599,11 @@ static int ntfs_attr_find(const ATTR_TYPE type, const ntfschar *name, /* * Iterate over attributes in mft record starting at @ctx->attr, or the - * attribute following that, if @ctx->is_first is TRUE. + * attribute following that, if @ctx->is_first is 'true'. */ if (ctx->is_first) { a = ctx->attr; - ctx->is_first = FALSE; + ctx->is_first = false; } else a = (ATTR_RECORD*)((u8*)ctx->attr + le32_to_cpu(ctx->attr->length)); @@ -890,11 +890,11 @@ static int ntfs_external_attr_find(const ATTR_TYPE type, ctx->al_entry = (ATTR_LIST_ENTRY*)al_start; /* * Iterate over entries in attribute list starting at @ctx->al_entry, - * or the entry following that, if @ctx->is_first is TRUE. + * or the entry following that, if @ctx->is_first is 'true'. */ if (ctx->is_first) { al_entry = ctx->al_entry; - ctx->is_first = FALSE; + ctx->is_first = false; } else al_entry = (ATTR_LIST_ENTRY*)((u8*)ctx->al_entry + le16_to_cpu(ctx->al_entry->length)); @@ -1127,7 +1127,7 @@ not_found: ctx->mrec = ctx->base_mrec; ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec + le16_to_cpu(ctx->mrec->attrs_offset)); - ctx->is_first = TRUE; + ctx->is_first = true; ctx->ntfs_ino = base_ni; ctx->base_ntfs_ino = NULL; ctx->base_mrec = NULL; @@ -1224,7 +1224,7 @@ static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx, /* Sanity checks are performed elsewhere. */ .attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset)), - .is_first = TRUE, + .is_first = true, .ntfs_ino = ni, }; } @@ -1243,7 +1243,7 @@ void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx) { if (likely(!ctx->base_ntfs_ino)) { /* No attribute list. */ - ctx->is_first = TRUE; + ctx->is_first = true; /* Sanity checks are performed elsewhere. */ ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec + le16_to_cpu(ctx->mrec->attrs_offset)); @@ -1585,7 +1585,7 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size) return -ENOMEM; /* Start by allocating clusters to hold the attribute value. */ rl = ntfs_cluster_alloc(vol, 0, new_size >> - vol->cluster_size_bits, -1, DATA_ZONE, TRUE); + vol->cluster_size_bits, -1, DATA_ZONE, true); if (IS_ERR(rl)) { err = PTR_ERR(rl); ntfs_debug("Failed to allocate cluster%s, error code " @@ -1919,7 +1919,7 @@ s64 ntfs_attr_extend_allocation(ntfs_inode *ni, s64 new_alloc_size, unsigned long flags; int err, mp_size; u32 attr_len = 0; /* Silence stupid gcc warning. */ - BOOL mp_rebuilt; + bool mp_rebuilt; #ifdef NTFS_DEBUG read_lock_irqsave(&ni->size_lock, flags); @@ -2222,7 +2222,7 @@ first_alloc: rl2 = ntfs_cluster_alloc(vol, allocated_size >> vol->cluster_size_bits, (new_alloc_size - allocated_size) >> vol->cluster_size_bits, (rl && (rl->lcn >= 0)) ? - rl->lcn + rl->length : -1, DATA_ZONE, TRUE); + rl->lcn + rl->length : -1, DATA_ZONE, true); if (IS_ERR(rl2)) { err = PTR_ERR(rl2); if (start < 0 || start >= allocated_size) @@ -2265,7 +2265,7 @@ first_alloc: BUG_ON(!rl2); BUG_ON(!rl2->length); BUG_ON(rl2->lcn < LCN_HOLE); - mp_rebuilt = FALSE; + mp_rebuilt = false; /* Get the size for the new mapping pairs array for this extent. */ mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1); if (unlikely(mp_size <= 0)) { @@ -2300,7 +2300,7 @@ first_alloc: err = -EOPNOTSUPP; goto undo_alloc; } - mp_rebuilt = TRUE; + mp_rebuilt = true; /* Generate the mapping pairs array directly into the attr record. */ err = ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(a->data.non_resident.mapping_pairs_offset), diff --git a/fs/ntfs/attrib.h b/fs/ntfs/attrib.h index 9074886b44b..3c8b74c99b8 100644 --- a/fs/ntfs/attrib.h +++ b/fs/ntfs/attrib.h @@ -40,10 +40,10 @@ * Structure must be initialized to zero before the first call to one of the * attribute search functions. Initialize @mrec to point to the mft record to * search, and @attr to point to the first attribute within @mrec (not necessary - * if calling the _first() functions), and set @is_first to TRUE (not necessary + * if calling the _first() functions), and set @is_first to 'true' (not necessary * if calling the _first() functions). * - * If @is_first is TRUE, the search begins with @attr. If @is_first is FALSE, + * If @is_first is 'true', the search begins with @attr. If @is_first is 'false', * the search begins after @attr. This is so that, after the first call to one * of the search attribute functions, we can call the function again, without * any modification of the search context, to automagically get the next @@ -52,7 +52,7 @@ typedef struct { MFT_RECORD *mrec; ATTR_RECORD *attr; - BOOL is_first; + bool is_first; ntfs_inode *ntfs_ino; ATTR_LIST_ENTRY *al_entry; ntfs_inode *base_ntfs_ino; @@ -65,7 +65,7 @@ extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn, extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn); extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, - const BOOL write_locked); + const bool write_locked); extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, ntfs_attr_search_ctx *ctx); diff --git a/fs/ntfs/bitmap.c b/fs/ntfs/bitmap.c index 7a190cdc60e..0809cf87609 100644 --- a/fs/ntfs/bitmap.c +++ b/fs/ntfs/bitmap.c @@ -34,18 +34,18 @@ * @start_bit: first bit to set * @count: number of bits to set * @value: value to set the bits to (i.e. 0 or 1) - * @is_rollback: if TRUE this is a rollback operation + * @is_rollback: if 'true' this is a rollback operation * * Set @count bits starting at bit @start_bit in the bitmap described by the * vfs inode @vi to @value, where @value is either 0 or 1. * - * @is_rollback should always be FALSE, it is for internal use to rollback + * @is_rollback should always be 'false', it is for internal use to rollback * errors. You probably want to use ntfs_bitmap_set_bits_in_run() instead. * * Return 0 on success and -errno on error. */ int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit, - const s64 count, const u8 value, const BOOL is_rollback) + const s64 count, const u8 value, const bool is_rollback) { s64 cnt = count; pgoff_t index, end_index; @@ -172,7 +172,7 @@ rollback: return PTR_ERR(page); if (count != cnt) pos = __ntfs_bitmap_set_bits_in_run(vi, start_bit, count - cnt, - value ? 0 : 1, TRUE); + value ? 0 : 1, true); else pos = 0; if (!pos) { diff --git a/fs/ntfs/bitmap.h b/fs/ntfs/bitmap.h index bb50d6bc921..72c9ad8be70 100644 --- a/fs/ntfs/bitmap.h +++ b/fs/ntfs/bitmap.h @@ -30,7 +30,7 @@ #include "types.h" extern int __ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit, - const s64 count, const u8 value, const BOOL is_rollback); + const s64 count, const u8 value, const bool is_rollback); /** * ntfs_bitmap_set_bits_in_run - set a run of bits in a bitmap to a value @@ -48,7 +48,7 @@ static inline int ntfs_bitmap_set_bits_in_run(struct inode *vi, const s64 start_bit, const s64 count, const u8 value) { return __ntfs_bitmap_set_bits_in_run(vi, start_bit, count, value, - FALSE); + false); } /** diff --git a/fs/ntfs/collate.h b/fs/ntfs/collate.h index e027f36fcc2..aba83347e5f 100644 --- a/fs/ntfs/collate.h +++ b/fs/ntfs/collate.h @@ -26,7 +26,7 @@ #include "types.h" #include "volume.h" -static inline BOOL ntfs_is_collation_rule_supported(COLLATION_RULE cr) { +static inline bool ntfs_is_collation_rule_supported(COLLATION_RULE cr) { int i; /* @@ -35,12 +35,12 @@ static inline BOOL ntfs_is_collation_rule_supported(COLLATION_RULE cr) { * now. */ if (unlikely(cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG)) - return FALSE; + return false; i = le32_to_cpu(cr); if (likely(((i >= 0) && (i <= 0x02)) || ((i >= 0x10) && (i <= 0x13)))) - return TRUE; - return FALSE; + return true; + return false; } extern int ntfs_collate(ntfs_volume *vol, COLLATION_RULE cr, diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c index 68a607ff9fd..d98daf59e0b 100644 --- a/fs/ntfs/compress.c +++ b/fs/ntfs/compress.c @@ -600,7 +600,7 @@ do_next_cb: rl = NULL; for (vcn = start_vcn, start_vcn += cb_clusters; vcn < start_vcn; vcn++) { - BOOL is_retry = FALSE; + bool is_retry = false; if (!rl) { lock_retry_remap: @@ -626,7 +626,7 @@ lock_retry_remap: break; if (is_retry || lcn != LCN_RL_NOT_MAPPED) goto rl_err; - is_retry = TRUE; + is_retry = true; /* * Attempt to map runlist, dropping lock for the * duration. diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 2e42c2dcae1..585a79d39c9 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -509,7 +509,7 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, u32 attr_rec_len = 0; unsigned blocksize, u; int err, mp_size; - BOOL rl_write_locked, was_hole, is_retry; + bool rl_write_locked, was_hole, is_retry; unsigned char blocksize_bits; struct { u8 runlist_merged:1; @@ -543,13 +543,13 @@ static int ntfs_prepare_pages_for_non_resident_write(struct page **pages, return -ENOMEM; } } while (++u < nr_pages); - rl_write_locked = FALSE; + rl_write_locked = false; rl = NULL; err = 0; vcn = lcn = -1; vcn_len = 0; lcn_block = -1; - was_hole = FALSE; + was_hole = false; cpos = pos >> vol->cluster_size_bits; end = pos + bytes; cend = (end + vol->cluster_size - 1) >> vol->cluster_size_bits; @@ -760,7 +760,7 @@ map_buffer_cached: } continue; } - is_retry = FALSE; + is_retry = false; if (!rl) { down_read(&ni->runlist.lock); retry_remap: @@ -776,7 +776,7 @@ retry_remap: * Successful remap, setup the map cache and * use that to deal with the buffer. */ - was_hole = FALSE; + was_hole = false; vcn = bh_cpos; vcn_len = rl[1].vcn - vcn; lcn_block = lcn << (vol->cluster_size_bits - @@ -792,7 +792,7 @@ retry_remap: if (likely(vcn + vcn_len >= cend)) { if (rl_write_locked) { up_write(&ni->runlist.lock); - rl_write_locked = FALSE; + rl_write_locked = false; } else up_read(&ni->runlist.lock); rl = NULL; @@ -818,13 +818,13 @@ retry_remap: */ up_read(&ni->runlist.lock); down_write(&ni->runlist.lock); - rl_write_locked = TRUE; + rl_write_locked = true; goto retry_remap; } err = ntfs_map_runlist_nolock(ni, bh_cpos, NULL); if (likely(!err)) { - is_retry = TRUE; + is_retry = true; goto retry_remap; } /* @@ -903,7 +903,7 @@ rl_not_mapped_enoent: if (!rl_write_locked) { up_read(&ni->runlist.lock); down_write(&ni->runlist.lock); - rl_write_locked = TRUE; + rl_write_locked = true; goto retry_remap; } /* Find the previous last allocated cluster. */ @@ -917,7 +917,7 @@ rl_not_mapped_enoent: } } rl2 = ntfs_cluster_alloc(vol, bh_cpos, 1, lcn, DATA_ZONE, - FALSE); + false); if (IS_ERR(rl2)) { err = PTR_ERR(rl2); ntfs_debug("Failed to allocate cluster, error code %i.", @@ -1093,7 +1093,7 @@ rl_not_mapped_enoent: status.mft_attr_mapped = 0; status.mp_rebuilt = 0; /* Setup the map cache and use that to deal with the buffer. */ - was_hole = TRUE; + was_hole = true; vcn = bh_cpos; vcn_len = 1; lcn_block = lcn << (vol->cluster_size_bits - blocksize_bits); @@ -1105,7 +1105,7 @@ rl_not_mapped_enoent: */ if (likely(vcn + vcn_len >= cend)) { up_write(&ni->runlist.lock); - rl_write_locked = FALSE; + rl_write_locked = false; rl = NULL; } goto map_buffer_cached; @@ -1117,7 +1117,7 @@ rl_not_mapped_enoent: if (likely(!err)) { if (unlikely(rl_write_locked)) { up_write(&ni->runlist.lock); - rl_write_locked = FALSE; + rl_write_locked = false; } else if (unlikely(rl)) up_read(&ni->runlist.lock); rl = NULL; @@ -1528,19 +1528,19 @@ static inline int ntfs_commit_pages_after_non_resident_write( do { s64 bh_pos; struct page *page; - BOOL partial; + bool partial; page = pages[u]; bh_pos = (s64)page->index << PAGE_CACHE_SHIFT; bh = head = page_buffers(page); - partial = FALSE; + partial = false; do { s64 bh_end; bh_end = bh_pos + blocksize; if (bh_end <= pos || bh_pos >= end) { if (!buffer_uptodate(bh)) - partial = TRUE; + partial = true; } else { set_buffer_uptodate(bh); mark_buffer_dirty(bh); @@ -1997,7 +1997,7 @@ static ssize_t ntfs_file_buffered_write(struct kiocb *iocb, */ down_read(&ni->runlist.lock); lcn = ntfs_attr_vcn_to_lcn_nolock(ni, pos >> - vol->cluster_size_bits, FALSE); + vol->cluster_size_bits, false); up_read(&ni->runlist.lock); if (unlikely(lcn < LCN_HOLE)) { status = -EIO; diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c index 9f5427c2d10..e32cde48636 100644 --- a/fs/ntfs/index.c +++ b/fs/ntfs/index.c @@ -204,7 +204,7 @@ int ntfs_index_lookup(const void *key, const int key_len, if ((key_len == le16_to_cpu(ie->key_length)) && !memcmp(key, &ie->key, key_len)) { ir_done: - ictx->is_in_root = TRUE; + ictx->is_in_root = true; ictx->ir = ir; ictx->actx = actx; ictx->base_ni = base_ni; @@ -374,7 +374,7 @@ fast_descend_into_child_node: if ((key_len == le16_to_cpu(ie->key_length)) && !memcmp(key, &ie->key, key_len)) { ia_done: - ictx->is_in_root = FALSE; + ictx->is_in_root = false; ictx->actx = NULL; ictx->base_ni = NULL; ictx->ia = ia; diff --git a/fs/ntfs/index.h b/fs/ntfs/index.h index 846a489e869..8745469c398 100644 --- a/fs/ntfs/index.h +++ b/fs/ntfs/index.h @@ -37,12 +37,12 @@ * @entry: index entry (points into @ir or @ia) * @data: index entry data (points into @entry) * @data_len: length in bytes of @data - * @is_in_root: TRUE if @entry is in @ir and FALSE if it is in @ia + * @is_in_root: 'true' if @entry is in @ir and 'false' if it is in @ia * @ir: index root if @is_in_root and NULL otherwise * @actx: attribute search context if @is_in_root and NULL otherwise * @base_ni: base inode if @is_in_root and NULL otherwise - * @ia: index block if @is_in_root is FALSE and NULL otherwise - * @page: page if @is_in_root is FALSE and NULL otherwise + * @ia: index block if @is_in_root is 'false' and NULL otherwise + * @page: page if @is_in_root is 'false' and NULL otherwise * * @idx_ni is the index inode this context belongs to. * @@ -50,11 +50,11 @@ * are the index entry data and its length in bytes, respectively. @data * simply points into @entry. This is probably what the user is interested in. * - * If @is_in_root is TRUE, @entry is in the index root attribute @ir described + * If @is_in_root is 'true', @entry is in the index root attribute @ir described * by the attribute search context @actx and the base inode @base_ni. @ia and * @page are NULL in this case. * - * If @is_in_root is FALSE, @entry is in the index allocation attribute and @ia + * If @is_in_root is 'false', @entry is in the index allocation attribute and @ia * and @page point to the index allocation block and the mapped, locked page it * is in, respectively. @ir, @actx and @base_ni are NULL in this case. * @@ -77,7 +77,7 @@ typedef struct { INDEX_ENTRY *entry; void *data; u16 data_len; - BOOL is_in_root; + bool is_in_root; INDEX_ROOT *ir; ntfs_attr_search_ctx *actx; ntfs_inode *base_ni; diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 933dbd89c2a..2d3de9c8981 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -2301,7 +2301,7 @@ void ntfs_clear_big_inode(struct inode *vi) } #ifdef NTFS_RW if (NInoDirty(ni)) { - BOOL was_bad = (is_bad_inode(vi)); + bool was_bad = (is_bad_inode(vi)); /* Committing the inode also commits all extent inodes. */ ntfs_commit_inode(vi); @@ -3015,7 +3015,7 @@ int ntfs_write_inode(struct inode *vi, int sync) MFT_RECORD *m; STANDARD_INFORMATION *si; int err = 0; - BOOL modified = FALSE; + bool modified = false; ntfs_debug("Entering for %sinode 0x%lx.", NInoAttr(ni) ? "attr " : "", vi->i_ino); @@ -3057,7 +3057,7 @@ int ntfs_write_inode(struct inode *vi, int sync) sle64_to_cpu(si->last_data_change_time), (long long)sle64_to_cpu(nt)); si->last_data_change_time = nt; - modified = TRUE; + modified = true; } nt = utc2ntfs(vi->i_ctime); if (si->last_mft_change_time != nt) { @@ -3066,7 +3066,7 @@ int ntfs_write_inode(struct inode *vi, int sync) sle64_to_cpu(si->last_mft_change_time), (long long)sle64_to_cpu(nt)); si->last_mft_change_time = nt; - modified = TRUE; + modified = true; } nt = utc2ntfs(vi->i_atime); if (si->last_access_time != nt) { @@ -3075,7 +3075,7 @@ int ntfs_write_inode(struct inode *vi, int sync) (long long)sle64_to_cpu(si->last_access_time), (long long)sle64_to_cpu(nt)); si->last_access_time = nt; - modified = TRUE; + modified = true; } /* * If we just modified the standard information attribute we need to diff --git a/fs/ntfs/layout.h b/fs/ntfs/layout.h index d34b93cb8b4..1e383328ece 100644 --- a/fs/ntfs/layout.h +++ b/fs/ntfs/layout.h @@ -142,13 +142,13 @@ typedef le32 NTFS_RECORD_TYPE; * operator! (-8 */ -static inline BOOL __ntfs_is_magic(le32 x, NTFS_RECORD_TYPE r) +static inline bool __ntfs_is_magic(le32 x, NTFS_RECORD_TYPE r) { return (x == r); } #define ntfs_is_magic(x, m) __ntfs_is_magic(x, magic_##m) -static inline BOOL __ntfs_is_magicp(le32 *p, NTFS_RECORD_TYPE r) +static inline bool __ntfs_is_magicp(le32 *p, NTFS_RECORD_TYPE r) { return (*p == r); } @@ -323,7 +323,7 @@ typedef le64 leMFT_REF; #define MREF_LE(x) ((unsigned long)(le64_to_cpu(x) & MFT_REF_MASK_CPU)) #define MSEQNO_LE(x) ((u16)((le64_to_cpu(x) >> 48) & 0xffff)) -#define IS_ERR_MREF(x) (((x) & 0x0000800000000000ULL) ? 1 : 0) +#define IS_ERR_MREF(x) (((x) & 0x0000800000000000ULL) ? true : false) #define ERR_MREF(x) ((u64)((s64)(x))) #define MREF_ERR(x) ((int)((s64)(x))) diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c index 29cabf93d2d..1711b710b64 100644 --- a/fs/ntfs/lcnalloc.c +++ b/fs/ntfs/lcnalloc.c @@ -76,7 +76,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, * @count: number of clusters to allocate * @start_lcn: starting lcn at which to allocate the clusters (or -1 if none) * @zone: zone from which to allocate the clusters - * @is_extension: if TRUE, this is an attribute extension + * @is_extension: if 'true', this is an attribute extension * * Allocate @count clusters preferably starting at cluster @start_lcn or at the * current allocator position if @start_lcn is -1, on the mounted ntfs volume @@ -87,11 +87,11 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, * @start_vcn specifies the vcn of the first allocated cluster. This makes * merging the resulting runlist with the old runlist easier. * - * If @is_extension is TRUE, the caller is allocating clusters to extend an - * attribute and if it is FALSE, the caller is allocating clusters to fill a + * If @is_extension is 'true', the caller is allocating clusters to extend an + * attribute and if it is 'false', the caller is allocating clusters to fill a * hole in an attribute. Practically the difference is that if @is_extension - * is TRUE the returned runlist will be terminated with LCN_ENOENT and if - * @is_extension is FALSE the runlist will be terminated with + * is 'true' the returned runlist will be terminated with LCN_ENOENT and if + * @is_extension is 'false' the runlist will be terminated with * LCN_RL_NOT_MAPPED. * * You need to check the return value with IS_ERR(). If this is false, the @@ -146,7 +146,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, const s64 count, const LCN start_lcn, const NTFS_CLUSTER_ALLOCATION_ZONES zone, - const BOOL is_extension) + const bool is_extension) { LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn; LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size; @@ -818,7 +818,7 @@ out: * Assuming you cache ctx->attr in a variable @a of type ATTR_RECORD * and that * you cache ctx->mrec in a variable @m of type MFT_RECORD *. * - * @is_rollback should always be FALSE, it is for internal use to rollback + * @is_rollback should always be 'false', it is for internal use to rollback * errors. You probably want to use ntfs_cluster_free() instead. * * Note, __ntfs_cluster_free() does not modify the runlist, so you have to @@ -828,7 +828,7 @@ out: * success and -errno on error. * * WARNING: If @ctx is supplied, regardless of whether success or failure is - * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx * is no longer valid, i.e. you need to either call * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. * In that case PTR_ERR(@ctx->mrec) will give you the error code for @@ -847,7 +847,7 @@ out: * and it will be left mapped on return. */ s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, - ntfs_attr_search_ctx *ctx, const BOOL is_rollback) + ntfs_attr_search_ctx *ctx, const bool is_rollback) { s64 delta, to_free, total_freed, real_freed; ntfs_volume *vol; @@ -999,7 +999,7 @@ err_out: * If rollback fails, set the volume errors flag, emit an error * message, and return the error code. */ - delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, TRUE); + delta = __ntfs_cluster_free(ni, start_vcn, total_freed, ctx, true); if (delta < 0) { ntfs_error(vol->sb, "Failed to rollback (error %i). Leaving " "inconsistent metadata! Unmount and run " diff --git a/fs/ntfs/lcnalloc.h b/fs/ntfs/lcnalloc.h index 72cbca7003b..2adb0431694 100644 --- a/fs/ntfs/lcnalloc.h +++ b/fs/ntfs/lcnalloc.h @@ -43,10 +43,10 @@ typedef enum { extern runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn, const s64 count, const LCN start_lcn, const NTFS_CLUSTER_ALLOCATION_ZONES zone, - const BOOL is_extension); + const bool is_extension); extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, - s64 count, ntfs_attr_search_ctx *ctx, const BOOL is_rollback); + s64 count, ntfs_attr_search_ctx *ctx, const bool is_rollback); /** * ntfs_cluster_free - free clusters on an ntfs volume @@ -86,7 +86,7 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, * success and -errno on error. * * WARNING: If @ctx is supplied, regardless of whether success or failure is - * returned, you need to check IS_ERR(@ctx->mrec) and if TRUE the @ctx + * returned, you need to check IS_ERR(@ctx->mrec) and if 'true' the @ctx * is no longer valid, i.e. you need to either call * ntfs_attr_reinit_search_ctx() or ntfs_attr_put_search_ctx() on it. * In that case PTR_ERR(@ctx->mrec) will give you the error code for @@ -107,7 +107,7 @@ extern s64 __ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, static inline s64 ntfs_cluster_free(ntfs_inode *ni, const VCN start_vcn, s64 count, ntfs_attr_search_ctx *ctx) { - return __ntfs_cluster_free(ni, start_vcn, count, ctx, FALSE); + return __ntfs_cluster_free(ni, start_vcn, count, ctx, false); } extern int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol, diff --git a/fs/ntfs/logfile.c b/fs/ntfs/logfile.c index 4af2ad1193e..acfed325f4e 100644 --- a/fs/ntfs/logfile.c +++ b/fs/ntfs/logfile.c @@ -41,18 +41,18 @@ * @rp: restart page header to check * @pos: position in @vi at which the restart page header resides * - * Check the restart page header @rp for consistency and return TRUE if it is - * consistent and FALSE otherwise. + * Check the restart page header @rp for consistency and return 'true' if it is + * consistent and 'false' otherwise. * * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not * require the full restart page. */ -static BOOL ntfs_check_restart_page_header(struct inode *vi, +static bool ntfs_check_restart_page_header(struct inode *vi, RESTART_PAGE_HEADER *rp, s64 pos) { u32 logfile_system_page_size, logfile_log_page_size; u16 ra_ofs, usa_count, usa_ofs, usa_end = 0; - BOOL have_usa = TRUE; + bool have_usa = true; ntfs_debug("Entering."); /* @@ -67,7 +67,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, (logfile_system_page_size - 1) || logfile_log_page_size & (logfile_log_page_size - 1)) { ntfs_error(vi->i_sb, "$LogFile uses unsupported page size."); - return FALSE; + return false; } /* * We must be either at !pos (1st restart page) or at pos = system page @@ -76,7 +76,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, if (pos && pos != logfile_system_page_size) { ntfs_error(vi->i_sb, "Found restart area in incorrect " "position in $LogFile."); - return FALSE; + return false; } /* We only know how to handle version 1.1. */ if (sle16_to_cpu(rp->major_ver) != 1 || @@ -85,14 +85,14 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, "supported. (This driver supports version " "1.1 only.)", (int)sle16_to_cpu(rp->major_ver), (int)sle16_to_cpu(rp->minor_ver)); - return FALSE; + return false; } /* * If chkdsk has been run the restart page may not be protected by an * update sequence array. */ if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) { - have_usa = FALSE; + have_usa = false; goto skip_usa_checks; } /* Verify the size of the update sequence array. */ @@ -100,7 +100,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, if (usa_count != le16_to_cpu(rp->usa_count)) { ntfs_error(vi->i_sb, "$LogFile restart page specifies " "inconsistent update sequence array count."); - return FALSE; + return false; } /* Verify the position of the update sequence array. */ usa_ofs = le16_to_cpu(rp->usa_ofs); @@ -109,7 +109,7 @@ static BOOL ntfs_check_restart_page_header(struct inode *vi, usa_end > NTFS_BLOCK_SIZE - sizeof(u16)) { ntfs_error(vi->i_sb, "$LogFile restart page specifies " "inconsistent update sequence array offset."); - return FALSE; + return false; } skip_usa_checks: /* @@ -124,7 +124,7 @@ skip_usa_checks: ra_ofs > logfile_system_page_size) { ntfs_error(vi->i_sb, "$LogFile restart page specifies " "inconsistent restart area offset."); - return FALSE; + return false; } /* * Only restart pages modified by chkdsk are allowed to have chkdsk_lsn @@ -133,10 +133,10 @@ skip_usa_checks: if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) { ntfs_error(vi->i_sb, "$LogFile restart page is not modified " "by chkdsk but a chkdsk LSN is specified."); - return FALSE; + return false; } ntfs_debug("Done."); - return TRUE; + return true; } /** @@ -145,7 +145,7 @@ skip_usa_checks: * @rp: restart page whose restart area to check * * Check the restart area of the restart page @rp for consistency and return - * TRUE if it is consistent and FALSE otherwise. + * 'true' if it is consistent and 'false' otherwise. * * This function assumes that the restart page header has already been * consistency checked. @@ -153,7 +153,7 @@ skip_usa_checks: * This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not * require the full restart page. */ -static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) +static bool ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) { u64 file_size; RESTART_AREA *ra; @@ -172,7 +172,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) NTFS_BLOCK_SIZE - sizeof(u16)) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent file offset."); - return FALSE; + return false; } /* * Now that we can access ra->client_array_offset, make sure everything @@ -186,7 +186,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) ra_ofs + ca_ofs > NTFS_BLOCK_SIZE - sizeof(u16)) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent client array offset."); - return FALSE; + return false; } /* * The restart area must end within the system page size both when @@ -203,7 +203,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) "of the system page size specified by the " "restart page header and/or the specified " "restart area length is inconsistent."); - return FALSE; + return false; } /* * The ra->client_free_list and ra->client_in_use_list must be either @@ -218,7 +218,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) le16_to_cpu(ra->log_clients))) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "overflowing client free and/or in use lists."); - return FALSE; + return false; } /* * Check ra->seq_number_bits against ra->file_size for consistency. @@ -233,24 +233,24 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) if (le32_to_cpu(ra->seq_number_bits) != 67 - fs_bits) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent sequence number bits."); - return FALSE; + return false; } /* The log record header length must be a multiple of 8. */ if (((le16_to_cpu(ra->log_record_header_length) + 7) & ~7) != le16_to_cpu(ra->log_record_header_length)) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent log record header length."); - return FALSE; + return false; } /* Dito for the log page data offset. */ if (((le16_to_cpu(ra->log_page_data_offset) + 7) & ~7) != le16_to_cpu(ra->log_page_data_offset)) { ntfs_error(vi->i_sb, "$LogFile restart area specifies " "inconsistent log page data offset."); - return FALSE; + return false; } ntfs_debug("Done."); - return TRUE; + return true; } /** @@ -259,7 +259,7 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) * @rp: restart page whose log client array to check * * Check the log client array of the restart page @rp for consistency and - * return TRUE if it is consistent and FALSE otherwise. + * return 'true' if it is consistent and 'false' otherwise. * * This function assumes that the restart page header and the restart area have * already been consistency checked. @@ -268,13 +268,13 @@ static BOOL ntfs_check_restart_area(struct inode *vi, RESTART_PAGE_HEADER *rp) * function needs @rp->system_page_size bytes in @rp, i.e. it requires the full * restart page and the page must be multi sector transfer deprotected. */ -static BOOL ntfs_check_log_client_array(struct inode *vi, +static bool ntfs_check_log_client_array(struct inode *vi, RESTART_PAGE_HEADER *rp) { RESTART_AREA *ra; LOG_CLIENT_RECORD *ca, *cr; u16 nr_clients, idx; - BOOL in_free_list, idx_is_first; + bool in_free_list, idx_is_first; ntfs_debug("Entering."); ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset)); @@ -290,9 +290,9 @@ static BOOL ntfs_check_log_client_array(struct inode *vi, */ nr_clients = le16_to_cpu(ra->log_clients); idx = le16_to_cpu(ra->client_free_list); - in_free_list = TRUE; + in_free_list = true; check_list: - for (idx_is_first = TRUE; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--, + for (idx_is_first = true; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--, idx = le16_to_cpu(cr->next_client)) { if (!nr_clients || idx >= le16_to_cpu(ra->log_clients)) goto err_out; @@ -302,20 +302,20 @@ check_list: if (idx_is_first) { if (cr->prev_client != LOGFILE_NO_CLIENT) goto err_out; - idx_is_first = FALSE; + idx_is_first = false; } } /* Switch to and check the in use list if we just did the free list. */ if (in_free_list) { - in_free_list = FALSE; + in_free_list = false; idx = le16_to_cpu(ra->client_in_use_list); goto check_list; } ntfs_debug("Done."); - return TRUE; + return true; err_out: ntfs_error(vi->i_sb, "$LogFile log client array is corrupt."); - return FALSE; + return false; } /** @@ -468,8 +468,8 @@ err_out: * @log_vi: struct inode of loaded journal $LogFile to check * @rp: [OUT] on success this is a copy of the current restart page * - * Check the $LogFile journal for consistency and return TRUE if it is - * consistent and FALSE if not. On success, the current restart page is + * Check the $LogFile journal for consistency and return 'true' if it is + * consistent and 'false' if not. On success, the current restart page is * returned in *@rp. Caller must call ntfs_free(*@rp) when finished with it. * * At present we only check the two restart pages and ignore the log record @@ -480,7 +480,7 @@ err_out: * if the $LogFile was created on a system with a different page size to ours * yet and mst deprotection would fail if our page size is smaller. */ -BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) +bool ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) { s64 size, pos; LSN rstr1_lsn, rstr2_lsn; @@ -491,7 +491,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) RESTART_PAGE_HEADER *rstr1_ph = NULL; RESTART_PAGE_HEADER *rstr2_ph = NULL; int log_page_size, log_page_mask, err; - BOOL logfile_is_empty = TRUE; + bool logfile_is_empty = true; u8 log_page_bits; ntfs_debug("Entering."); @@ -527,7 +527,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) if (size < log_page_size * 2 || (size - log_page_size * 2) >> log_page_bits < MinLogRecordPages) { ntfs_error(vol->sb, "$LogFile is too small."); - return FALSE; + return false; } /* * Read through the file looking for a restart page. Since the restart @@ -556,7 +556,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) * means we are done. */ if (!ntfs_is_empty_recordp((le32*)kaddr)) - logfile_is_empty = FALSE; + logfile_is_empty = false; else if (!logfile_is_empty) break; /* @@ -615,13 +615,13 @@ BOOL ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp) NVolSetLogFileEmpty(vol); is_empty: ntfs_debug("Done. ($LogFile is empty.)"); - return TRUE; + return true; } if (!rstr1_ph) { BUG_ON(rstr2_ph); ntfs_error(vol->sb, "Did not find any restart pages in " "$LogFile and it was not empty."); - return FALSE; + return false; } /* If both restart pages were found, use the more recent one. */ if (rstr2_ph) { @@ -648,11 +648,11 @@ is_empty: else ntfs_free(rstr1_ph); ntfs_debug("Done."); - return TRUE; + return true; err_out: if (rstr1_ph) ntfs_free(rstr1_ph); - return FALSE; + return false; } /** @@ -660,8 +660,8 @@ err_out: * @log_vi: struct inode of loaded journal $LogFile to check * @rp: copy of the current restart page * - * Analyze the $LogFile journal and return TRUE if it indicates the volume was - * shutdown cleanly and FALSE if not. + * Analyze the $LogFile journal and return 'true' if it indicates the volume was + * shutdown cleanly and 'false' if not. * * At present we only look at the two restart pages and ignore the log record * pages. This is a little bit crude in that there will be a very small number @@ -675,7 +675,7 @@ err_out: * is empty this function requires that NVolLogFileEmpty() is true otherwise an * empty volume will be reported as dirty. */ -BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) +bool ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) { ntfs_volume *vol = NTFS_SB(log_vi->i_sb); RESTART_AREA *ra; @@ -684,7 +684,7 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) /* An empty $LogFile must have been clean before it got emptied. */ if (NVolLogFileEmpty(vol)) { ntfs_debug("Done. ($LogFile is empty.)"); - return TRUE; + return true; } BUG_ON(!rp); if (!ntfs_is_rstr_record(rp->magic) && @@ -693,7 +693,7 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) "probably a bug in that the $LogFile should " "have been consistency checked before calling " "this function."); - return FALSE; + return false; } ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset)); /* @@ -704,25 +704,25 @@ BOOL ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp) if (ra->client_in_use_list != LOGFILE_NO_CLIENT && !(ra->flags & RESTART_VOLUME_IS_CLEAN)) { ntfs_debug("Done. $LogFile indicates a dirty shutdown."); - return FALSE; + return false; } /* $LogFile indicates a clean shutdown. */ ntfs_debug("Done. $LogFile indicates a clean shutdown."); - return TRUE; + return true; } /** * ntfs_empty_logfile - empty the contents of the $LogFile journal * @log_vi: struct inode of loaded journal $LogFile to empty * - * Empty the contents of the $LogFile journal @log_vi and return TRUE on - * success and FALSE on error. + * Empty the contents of the $LogFile journal @log_vi and return 'true' on + * success and 'false' on error. * * This function assumes that the $LogFile journal has already been consistency * checked by a call to ntfs_check_logfile() and that ntfs_is_logfile_clean() * has been used to ensure that the $LogFile is clean. */ -BOOL ntfs_empty_logfile(struct inode *log_vi) +bool ntfs_empty_logfile(struct inode *log_vi) { ntfs_volume *vol = NTFS_SB(log_vi->i_sb); @@ -735,13 +735,13 @@ BOOL ntfs_empty_logfile(struct inode *log_vi) if (unlikely(err)) { ntfs_error(vol->sb, "Failed to fill $LogFile with " "0xff bytes (error code %i).", err); - return FALSE; + return false; } /* Set the flag so we do not have to do it again on remount. */ NVolSetLogFileEmpty(vol); } ntfs_debug("Done."); - return TRUE; + return true; } #endif /* NTFS_RW */ diff --git a/fs/ntfs/logfile.h b/fs/ntfs/logfile.h index a51f3dd0e9e..9468e1c45ae 100644 --- a/fs/ntfs/logfile.h +++ b/fs/ntfs/logfile.h @@ -296,13 +296,13 @@ typedef struct { /* sizeof() = 160 (0xa0) bytes */ } __attribute__ ((__packed__)) LOG_CLIENT_RECORD; -extern BOOL ntfs_check_logfile(struct inode *log_vi, +extern bool ntfs_check_logfile(struct inode *log_vi, RESTART_PAGE_HEADER **rp); -extern BOOL ntfs_is_logfile_clean(struct inode *log_vi, +extern bool ntfs_is_logfile_clean(struct inode *log_vi, const RESTART_PAGE_HEADER *rp); -extern BOOL ntfs_empty_logfile(struct inode *log_vi); +extern bool ntfs_empty_logfile(struct inode *log_vi); #endif /* NTFS_RW */ diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 584260fd684..2ad5c8b104b 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c @@ -251,7 +251,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref, int i; unsigned long mft_no = MREF(mref); u16 seq_no = MSEQNO(mref); - BOOL destroy_ni = FALSE; + bool destroy_ni = false; ntfs_debug("Mapping extent mft record 0x%lx (base mft record 0x%lx).", mft_no, base_ni->mft_no); @@ -322,7 +322,7 @@ map_err_out: if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) { ntfs_error(base_ni->vol->sb, "Found stale extent mft " "reference! Corrupt filesystem. Run chkdsk."); - destroy_ni = TRUE; + destroy_ni = true; m = ERR_PTR(-EIO); goto unm_err_out; } @@ -335,7 +335,7 @@ map_err_out: if (unlikely(!tmp)) { ntfs_error(base_ni->vol->sb, "Failed to allocate " "internal buffer."); - destroy_ni = TRUE; + destroy_ni = true; m = ERR_PTR(-ENOMEM); goto unm_err_out; } @@ -857,7 +857,7 @@ err_out: * caller is responsible for unlocking the ntfs inode and unpinning the base * vfs inode. * - * Return TRUE if the mft record may be written out and FALSE if not. + * Return 'true' if the mft record may be written out and 'false' if not. * * The caller has locked the page and cleared the uptodate flag on it which * means that we can safely write out any dirty mft records that do not have @@ -868,7 +868,7 @@ err_out: * Here is a description of the tests we perform: * * If the inode is found in icache we know the mft record must be a base mft - * record. If it is dirty, we do not write it and return FALSE as the vfs + * record. If it is dirty, we do not write it and return 'false' as the vfs * inode write paths will result in the access times being updated which would * cause the base mft record to be redirtied and written out again. (We know * the access time update will modify the base mft record because Windows @@ -877,11 +877,11 @@ err_out: * * If the inode is in icache and not dirty, we attempt to lock the mft record * and if we find the lock was already taken, it is not safe to write the mft - * record and we return FALSE. + * record and we return 'false'. * * If we manage to obtain the lock we have exclusive access to the mft record, * which also allows us safe writeout of the mft record. We then set - * @locked_ni to the locked ntfs inode and return TRUE. + * @locked_ni to the locked ntfs inode and return 'true'. * * Note we cannot just lock the mft record and sleep while waiting for the lock * because this would deadlock due to lock reversal (normally the mft record is @@ -891,24 +891,24 @@ err_out: * If the inode is not in icache we need to perform further checks. * * If the mft record is not a FILE record or it is a base mft record, we can - * safely write it and return TRUE. + * safely write it and return 'true'. * * We now know the mft record is an extent mft record. We check if the inode * corresponding to its base mft record is in icache and obtain a reference to - * it if it is. If it is not, we can safely write it and return TRUE. + * it if it is. If it is not, we can safely write it and return 'true'. * * We now have the base inode for the extent mft record. We check if it has an * ntfs inode for the extent mft record attached and if not it is safe to write - * the extent mft record and we return TRUE. + * the extent mft record and we return 'true'. * * The ntfs inode for the extent mft record is attached to the base inode so we * attempt to lock the extent mft record and if we find the lock was already - * taken, it is not safe to write the extent mft record and we return FALSE. + * taken, it is not safe to write the extent mft record and we return 'false'. * * If we manage to obtain the lock we have exclusive access to the extent mft * record, which also allows us safe writeout of the extent mft record. We * set the ntfs inode of the extent mft record clean and then set @locked_ni to - * the now locked ntfs inode and return TRUE. + * the now locked ntfs inode and return 'true'. * * Note, the reason for actually writing dirty mft records here and not just * relying on the vfs inode dirty code paths is that we can have mft records @@ -922,7 +922,7 @@ err_out: * appear if the mft record is reused for a new inode before it got written * out. */ -BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, +bool ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, const MFT_RECORD *m, ntfs_inode **locked_ni) { struct super_block *sb = vol->sb; @@ -977,7 +977,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, mft_no); atomic_dec(&ni->count); iput(vi); - return FALSE; + return false; } ntfs_debug("Inode 0x%lx is not dirty.", mft_no); /* The inode is not dirty, try to take the mft record lock. */ @@ -986,7 +986,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, "not write it.", mft_no); atomic_dec(&ni->count); iput(vi); - return FALSE; + return false; } ntfs_debug("Managed to lock mft record 0x%lx, write it.", mft_no); @@ -995,7 +995,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, * return the locked ntfs inode. */ *locked_ni = ni; - return TRUE; + return true; } ntfs_debug("Inode 0x%lx is not in icache.", mft_no); /* The inode is not in icache. */ @@ -1003,13 +1003,13 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, if (!ntfs_is_mft_record(m->magic)) { ntfs_debug("Mft record 0x%lx is not a FILE record, write it.", mft_no); - return TRUE; + return true; } /* Write the mft record if it is a base inode. */ if (!m->base_mft_record) { ntfs_debug("Mft record 0x%lx is a base record, write it.", mft_no); - return TRUE; + return true; } /* * This is an extent mft record. Check if the inode corresponding to @@ -1033,7 +1033,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, */ ntfs_debug("Base inode 0x%lx is not in icache, write the " "extent record.", na.mft_no); - return TRUE; + return true; } ntfs_debug("Base inode 0x%lx is in icache.", na.mft_no); /* @@ -1051,7 +1051,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, iput(vi); ntfs_debug("Base inode 0x%lx has no attached extent inodes, " "write the extent record.", na.mft_no); - return TRUE; + return true; } /* Iterate over the attached extent inodes. */ extent_nis = ni->ext.extent_ntfs_inos; @@ -1075,7 +1075,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, ntfs_debug("Extent inode 0x%lx is not attached to its base " "inode 0x%lx, write the extent record.", mft_no, na.mft_no); - return TRUE; + return true; } ntfs_debug("Extent inode 0x%lx is attached to its base inode 0x%lx.", mft_no, na.mft_no); @@ -1091,7 +1091,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, iput(vi); ntfs_debug("Extent mft record 0x%lx is already locked, do " "not write it.", mft_no); - return FALSE; + return false; } ntfs_debug("Managed to lock extent mft record 0x%lx, write it.", mft_no); @@ -1103,7 +1103,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, * the locked extent ntfs inode. */ *locked_ni = eni; - return TRUE; + return true; } static const char *es = " Leaving inconsistent metadata. Unmount and run " @@ -1354,7 +1354,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) ntfs_unmap_page(page); /* Allocate a cluster from the DATA_ZONE. */ rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE, - TRUE); + true); if (IS_ERR(rl2)) { up_write(&mftbmp_ni->runlist.lock); ntfs_error(vol->sb, "Failed to allocate a cluster for " @@ -1724,7 +1724,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) ATTR_RECORD *a = NULL; int ret, mp_size; u32 old_alen = 0; - BOOL mp_rebuilt = FALSE; + bool mp_rebuilt = false; ntfs_debug("Extending mft data allocation."); mft_ni = NTFS_I(vol->mft_ino); @@ -1780,7 +1780,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) old_last_vcn = rl[1].vcn; do { rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE, - TRUE); + true); if (likely(!IS_ERR(rl2))) break; if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) { @@ -1884,7 +1884,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) ret = -EOPNOTSUPP; goto undo_alloc; } - mp_rebuilt = TRUE; + mp_rebuilt = true; /* Generate the mapping pairs array directly into the attr record. */ ret = ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(a->data.non_resident.mapping_pairs_offset), @@ -2255,7 +2255,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, unsigned int ofs; int err; le16 seq_no, usn; - BOOL record_formatted = FALSE; + bool record_formatted = false; if (base_ni) { ntfs_debug("Entering (allocating an extent mft record for " @@ -2454,7 +2454,7 @@ have_alloc_rec: mft_ni->initialized_size = new_initialized_size; } write_unlock_irqrestore(&mft_ni->size_lock, flags); - record_formatted = TRUE; + record_formatted = true; /* Update the mft data attribute record to reflect the new sizes. */ m = map_mft_record(mft_ni); if (IS_ERR(m)) { diff --git a/fs/ntfs/mft.h b/fs/ntfs/mft.h index 639cd1bab08..b52bf87b99d 100644 --- a/fs/ntfs/mft.h +++ b/fs/ntfs/mft.h @@ -111,7 +111,7 @@ static inline int write_mft_record(ntfs_inode *ni, MFT_RECORD *m, int sync) return err; } -extern BOOL ntfs_may_write_mft_record(ntfs_volume *vol, +extern bool ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no, const MFT_RECORD *m, ntfs_inode **locked_ni); diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h index ddd3d503097..a12847ae467 100644 --- a/fs/ntfs/ntfs.h +++ b/fs/ntfs/ntfs.h @@ -105,7 +105,7 @@ extern int pre_write_mst_fixup(NTFS_RECORD *b, const u32 size); extern void post_write_mst_fixup(NTFS_RECORD *b); /* From fs/ntfs/unistr.c */ -extern BOOL ntfs_are_names_equal(const ntfschar *s1, size_t s1_len, +extern bool ntfs_are_names_equal(const ntfschar *s1, size_t s1_len, const ntfschar *s2, size_t s2_len, const IGNORE_CASE_BOOL ic, const ntfschar *upcase, const u32 upcase_size); diff --git a/fs/ntfs/quota.c b/fs/ntfs/quota.c index d0ef4182147..d80e3315cab 100644 --- a/fs/ntfs/quota.c +++ b/fs/ntfs/quota.c @@ -31,10 +31,10 @@ * ntfs_mark_quotas_out_of_date - mark the quotas out of date on an ntfs volume * @vol: ntfs volume on which to mark the quotas out of date * - * Mark the quotas out of date on the ntfs volume @vol and return TRUE on - * success and FALSE on error. + * Mark the quotas out of date on the ntfs volume @vol and return 'true' on + * success and 'false' on error. */ -BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol) +bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol) { ntfs_index_context *ictx; QUOTA_CONTROL_ENTRY *qce; @@ -46,7 +46,7 @@ BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol) goto done; if (!vol->quota_ino || !vol->quota_q_ino) { ntfs_error(vol->sb, "Quota inodes are not open."); - return FALSE; + return false; } mutex_lock(&vol->quota_q_ino->i_mutex); ictx = ntfs_index_ctx_get(NTFS_I(vol->quota_q_ino)); @@ -106,12 +106,12 @@ set_done: NVolSetQuotaOutOfDate(vol); done: ntfs_debug("Done."); - return TRUE; + return true; err_out: if (ictx) ntfs_index_ctx_put(ictx); mutex_unlock(&vol->quota_q_ino->i_mutex); - return FALSE; + return false; } #endif /* NTFS_RW */ diff --git a/fs/ntfs/quota.h b/fs/ntfs/quota.h index 40e4763aa22..4cbe5594c0b 100644 --- a/fs/ntfs/quota.h +++ b/fs/ntfs/quota.h @@ -28,7 +28,7 @@ #include "types.h" #include "volume.h" -extern BOOL ntfs_mark_quotas_out_of_date(ntfs_volume *vol); +extern bool ntfs_mark_quotas_out_of_date(ntfs_volume *vol); #endif /* NTFS_RW */ diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c index eb52b801512..9afd72c7ad0 100644 --- a/fs/ntfs/runlist.c +++ b/fs/ntfs/runlist.c @@ -149,10 +149,10 @@ static inline runlist_element *ntfs_rl_realloc_nofail(runlist_element *rl, * * It is up to the caller to serialize access to the runlists @dst and @src. * - * Return: TRUE Success, the runlists can be merged. - * FALSE Failure, the runlists cannot be merged. + * Return: true Success, the runlists can be merged. + * false Failure, the runlists cannot be merged. */ -static inline BOOL ntfs_are_rl_mergeable(runlist_element *dst, +static inline bool ntfs_are_rl_mergeable(runlist_element *dst, runlist_element *src) { BUG_ON(!dst); @@ -160,19 +160,19 @@ static inline BOOL ntfs_are_rl_mergeable(runlist_element *dst, /* We can merge unmapped regions even if they are misaligned. */ if ((dst->lcn == LCN_RL_NOT_MAPPED) && (src->lcn == LCN_RL_NOT_MAPPED)) - return TRUE; + return true; /* If the runs are misaligned, we cannot merge them. */ if ((dst->vcn + dst->length) != src->vcn) - return FALSE; + return false; /* If both runs are non-sparse and contiguous, we can merge them. */ if ((dst->lcn >= 0) && (src->lcn >= 0) && ((dst->lcn + dst->length) == src->lcn)) - return TRUE; + return true; /* If we are merging two holes, we can merge them. */ if ((dst->lcn == LCN_HOLE) && (src->lcn == LCN_HOLE)) - return TRUE; + return true; /* Cannot merge. */ - return FALSE; + return false; } /** @@ -218,7 +218,7 @@ static inline void __ntfs_rl_merge(runlist_element *dst, runlist_element *src) static inline runlist_element *ntfs_rl_append(runlist_element *dst, int dsize, runlist_element *src, int ssize, int loc) { - BOOL right = FALSE; /* Right end of @src needs merging. */ + bool right = false; /* Right end of @src needs merging. */ int marker; /* End of the inserted runs. */ BUG_ON(!dst); @@ -285,8 +285,8 @@ static inline runlist_element *ntfs_rl_append(runlist_element *dst, static inline runlist_element *ntfs_rl_insert(runlist_element *dst, int dsize, runlist_element *src, int ssize, int loc) { - BOOL left = FALSE; /* Left end of @src needs merging. */ - BOOL disc = FALSE; /* Discontinuity between @dst and @src. */ + bool left = false; /* Left end of @src needs merging. */ + bool disc = false; /* Discontinuity between @dst and @src. */ int marker; /* End of the inserted runs. */ BUG_ON(!dst); @@ -382,8 +382,8 @@ static inline runlist_element *ntfs_rl_replace(runlist_element *dst, int dsize, runlist_element *src, int ssize, int loc) { signed delta; - BOOL left = FALSE; /* Left end of @src needs merging. */ - BOOL right = FALSE; /* Right end of @src needs merging. */ + bool left = false; /* Left end of @src needs merging. */ + bool right = false; /* Right end of @src needs merging. */ int tail; /* Start of tail of @dst. */ int marker; /* End of the inserted runs. */ @@ -620,8 +620,8 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl, ; { - BOOL start; - BOOL finish; + bool start; + bool finish; int ds = dend + 1; /* Number of elements in drl & srl */ int ss = sfinal - sstart + 1; @@ -635,7 +635,7 @@ runlist_element *ntfs_runlists_merge(runlist_element *drl, if (finish && !drl[dins].length) ss++; if (marker && (drl[dins].vcn + drl[dins].length > srl[send - 1].vcn)) - finish = FALSE; + finish = false; #if 0 ntfs_debug("dfinal = %i, dend = %i", dfinal, dend); ntfs_debug("sstart = %i, sfinal = %i, send = %i", sstart, sfinal, send); @@ -1134,7 +1134,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, { LCN prev_lcn; int rls; - BOOL the_end = FALSE; + bool the_end = false; BUG_ON(first_vcn < 0); BUG_ON(last_vcn < -1); @@ -1168,7 +1168,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, s64 s1 = last_vcn + 1; if (unlikely(rl[1].vcn > s1)) length = s1 - rl->vcn; - the_end = TRUE; + the_end = true; } delta = first_vcn - rl->vcn; /* Header byte + length. */ @@ -1204,7 +1204,7 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, s64 s1 = last_vcn + 1; if (unlikely(rl[1].vcn > s1)) length = s1 - rl->vcn; - the_end = TRUE; + the_end = true; } /* Header byte + length. */ rls += 1 + ntfs_get_nr_significant_bytes(length); @@ -1327,7 +1327,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst, LCN prev_lcn; s8 *dst_max, *dst_next; int err = -ENOSPC; - BOOL the_end = FALSE; + bool the_end = false; s8 len_len, lcn_len; BUG_ON(first_vcn < 0); @@ -1370,7 +1370,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst, s64 s1 = last_vcn + 1; if (unlikely(rl[1].vcn > s1)) length = s1 - rl->vcn; - the_end = TRUE; + the_end = true; } delta = first_vcn - rl->vcn; /* Write length. */ @@ -1422,7 +1422,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst, s64 s1 = last_vcn + 1; if (unlikely(rl[1].vcn > s1)) length = s1 - rl->vcn; - the_end = TRUE; + the_end = true; } /* Write length. */ len_len = ntfs_write_significant_bytes(dst + 1, dst_max, @@ -1541,7 +1541,7 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist, */ if (rl->length) { runlist_element *trl; - BOOL is_end; + bool is_end; ntfs_debug("Shrinking runlist."); /* Determine the runlist size. */ @@ -1555,11 +1555,11 @@ int ntfs_rl_truncate_nolock(const ntfs_volume *vol, runlist *const runlist, * If a run was partially truncated, make the following runlist * element a terminator. */ - is_end = FALSE; + is_end = false; if (rl->length) { rl++; if (!rl->length) - is_end = TRUE; + is_end = true; rl->vcn = new_length; rl->length = 0; } @@ -1648,7 +1648,7 @@ int ntfs_rl_punch_nolock(const ntfs_volume *vol, runlist *const runlist, s64 delta; runlist_element *rl, *rl_end, *rl_real_end, *trl; int old_size; - BOOL lcn_fixup = FALSE; + bool lcn_fixup = false; ntfs_debug("Entering for start 0x%llx, length 0x%llx.", (long long)start, (long long)length); @@ -1862,7 +1862,7 @@ split_end: if (rl->lcn >= 0) { rl->lcn -= delta; /* Need this in case the lcn just became negative. */ - lcn_fixup = TRUE; + lcn_fixup = true; } rl->length += delta; goto split_end; diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 6b2712f10dd..03a391ac714 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -74,18 +74,18 @@ const option_t on_errors_arr[] = { * * Copied from old ntfs driver (which copied from vfat driver). */ -static int simple_getbool(char *s, BOOL *setval) +static int simple_getbool(char *s, bool *setval) { if (s) { if (!strcmp(s, "1") || !strcmp(s, "yes") || !strcmp(s, "true")) - *setval = TRUE; + *setval = true; else if (!strcmp(s, "0") || !strcmp(s, "no") || !strcmp(s, "false")) - *setval = FALSE; + *setval = false; else return 0; } else - *setval = TRUE; + *setval = true; return 1; } @@ -96,7 +96,7 @@ static int simple_getbool(char *s, BOOL *setval) * * Parse the recognized options in @opt for the ntfs volume described by @vol. */ -static BOOL parse_options(ntfs_volume *vol, char *opt) +static bool parse_options(ntfs_volume *vol, char *opt) { char *p, *v, *ov; static char *utf8 = "utf8"; @@ -137,7 +137,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt) } #define NTFS_GETOPT_BOOL(option, variable) \ if (!strcmp(p, option)) { \ - BOOL val; \ + bool val; \ if (!simple_getbool(v, &val)) \ goto needs_bool; \ variable = val; \ @@ -170,7 +170,7 @@ static BOOL parse_options(ntfs_volume *vol, char *opt) else NTFS_GETOPT_OCTAL("fmask", fmask) else NTFS_GETOPT_OCTAL("dmask", dmask) else NTFS_GETOPT("mft_zone_multiplier", mft_zone_multiplier) - else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE) + else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, true) else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files) else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive) else NTFS_GETOPT_BOOL("disable_sparse", disable_sparse) @@ -194,7 +194,7 @@ use_utf8: if (!old_nls) { ntfs_error(vol->sb, "NLS character set " "%s not found.", v); - return FALSE; + return false; } ntfs_error(vol->sb, "NLS character set %s not " "found. Using previous one %s.", @@ -205,14 +205,14 @@ use_utf8: unload_nls(old_nls); } } else if (!strcmp(p, "utf8")) { - BOOL val = FALSE; + bool val = false; ntfs_warning(vol->sb, "Option utf8 is no longer " "supported, using option nls=utf8. Please " "use option nls=utf8 in the future and " "make sure utf8 is compiled either as a " "module or into the kernel."); if (!v || !*v) - val = TRUE; + val = true; else if (!simple_getbool(v, &val)) goto needs_bool; if (val) { @@ -231,7 +231,7 @@ use_utf8: } no_mount_options: if (errors && !sloppy) - return FALSE; + return false; if (sloppy) ntfs_warning(vol->sb, "Sloppy option given. Ignoring " "unrecognized mount option(s) and continuing."); @@ -240,14 +240,14 @@ no_mount_options: if (!on_errors) { ntfs_error(vol->sb, "Invalid errors option argument " "or bug in options parser."); - return FALSE; + return false; } } if (nls_map) { if (vol->nls_map && vol->nls_map != nls_map) { ntfs_error(vol->sb, "Cannot change NLS character set " "on remount."); - return FALSE; + return false; } /* else (!vol->nls_map) */ ntfs_debug("Using NLS character set %s.", nls_map->charset); vol->nls_map = nls_map; @@ -257,7 +257,7 @@ no_mount_options: if (!vol->nls_map) { ntfs_error(vol->sb, "Failed to load default " "NLS character set."); - return FALSE; + return false; } ntfs_debug("Using default NLS character set (%s).", vol->nls_map->charset); @@ -268,7 +268,7 @@ no_mount_options: mft_zone_multiplier) { ntfs_error(vol->sb, "Cannot change mft_zone_multiplier " "on remount."); - return FALSE; + return false; } if (mft_zone_multiplier < 1 || mft_zone_multiplier > 4) { ntfs_error(vol->sb, "Invalid mft_zone_multiplier. " @@ -318,16 +318,16 @@ no_mount_options: NVolSetSparseEnabled(vol); } } - return TRUE; + return true; needs_arg: ntfs_error(vol->sb, "The %s option requires an argument.", p); - return FALSE; + return false; needs_bool: ntfs_error(vol->sb, "The %s option requires a boolean argument.", p); - return FALSE; + return false; needs_val: ntfs_error(vol->sb, "Invalid %s option argument: %s", p, ov); - return FALSE; + return false; } #ifdef NTFS_RW @@ -543,16 +543,16 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt) * is_boot_sector_ntfs - check whether a boot sector is a valid NTFS boot sector * @sb: Super block of the device to which @b belongs. * @b: Boot sector of device @sb to check. - * @silent: If TRUE, all output will be silenced. + * @silent: If 'true', all output will be silenced. * * is_boot_sector_ntfs() checks whether the boot sector @b is a valid NTFS boot - * sector. Returns TRUE if it is valid and FALSE if not. + * sector. Returns 'true' if it is valid and 'false' if not. * * @sb is only needed for warning/error output, i.e. it can be NULL when silent - * is TRUE. + * is 'true'. */ -static BOOL is_boot_sector_ntfs(const struct super_block *sb, - const NTFS_BOOT_SECTOR *b, const BOOL silent) +static bool is_boot_sector_ntfs(const struct super_block *sb, + const NTFS_BOOT_SECTOR *b, const bool silent) { /* * Check that checksum == sum of u32 values from b to the checksum @@ -620,9 +620,9 @@ static BOOL is_boot_sector_ntfs(const struct super_block *sb, */ if (!silent && b->end_of_sector_marker != const_cpu_to_le16(0xaa55)) ntfs_warning(sb, "Invalid end of sector marker."); - return TRUE; + return true; not_ntfs: - return FALSE; + return false; } /** @@ -732,9 +732,9 @@ hotfix_primary_boot_sector: * @b: boot sector to parse * * Parse the ntfs boot sector @b and store all imporant information therein in - * the ntfs super block @vol. Return TRUE on success and FALSE on error. + * the ntfs super block @vol. Return 'true' on success and 'false' on error. */ -static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) +static bool parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) { unsigned int sectors_per_cluster_bits, nr_hidden_sects; int clusters_per_mft_record, clusters_per_index_record; @@ -751,7 +751,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "device block size (%lu). This is not " "supported. Sorry.", vol->sector_size, vol->sb->s_blocksize); - return FALSE; + return false; } ntfs_debug("sectors_per_cluster = 0x%x", b->bpb.sectors_per_cluster); sectors_per_cluster_bits = ffs(b->bpb.sectors_per_cluster) - 1; @@ -770,7 +770,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) ntfs_error(vol->sb, "Cluster size (%i) is smaller than the " "sector size (%i). This is not supported. " "Sorry.", vol->cluster_size, vol->sector_size); - return FALSE; + return false; } clusters_per_mft_record = b->clusters_per_mft_record; ntfs_debug("clusters_per_mft_record = %i (0x%x)", @@ -802,7 +802,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "PAGE_CACHE_SIZE on your system (%lu). " "This is not supported. Sorry.", vol->mft_record_size, PAGE_CACHE_SIZE); - return FALSE; + return false; } /* We cannot support mft record sizes below the sector size. */ if (vol->mft_record_size < vol->sector_size) { @@ -810,7 +810,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "sector size (%i). This is not supported. " "Sorry.", vol->mft_record_size, vol->sector_size); - return FALSE; + return false; } clusters_per_index_record = b->clusters_per_index_record; ntfs_debug("clusters_per_index_record = %i (0x%x)", @@ -841,7 +841,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "the sector size (%i). This is not " "supported. Sorry.", vol->index_record_size, vol->sector_size); - return FALSE; + return false; } /* * Get the size of the volume in clusters and check for 64-bit-ness. @@ -851,7 +851,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) ll = sle64_to_cpu(b->number_of_sectors) >> sectors_per_cluster_bits; if ((u64)ll >= 1ULL << 32) { ntfs_error(vol->sb, "Cannot handle 64-bit clusters. Sorry."); - return FALSE; + return false; } vol->nr_clusters = ll; ntfs_debug("vol->nr_clusters = 0x%llx", (long long)vol->nr_clusters); @@ -867,7 +867,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) "Maximum supported is 2TiB. Sorry.", (unsigned long long)ll >> (40 - vol->cluster_size_bits)); - return FALSE; + return false; } } ll = sle64_to_cpu(b->mft_lcn); @@ -875,7 +875,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) ntfs_error(vol->sb, "MFT LCN (%lli, 0x%llx) is beyond end of " "volume. Weird.", (unsigned long long)ll, (unsigned long long)ll); - return FALSE; + return false; } vol->mft_lcn = ll; ntfs_debug("vol->mft_lcn = 0x%llx", (long long)vol->mft_lcn); @@ -884,7 +884,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) ntfs_error(vol->sb, "MFTMirr LCN (%lli, 0x%llx) is beyond end " "of volume. Weird.", (unsigned long long)ll, (unsigned long long)ll); - return FALSE; + return false; } vol->mftmirr_lcn = ll; ntfs_debug("vol->mftmirr_lcn = 0x%llx", (long long)vol->mftmirr_lcn); @@ -907,7 +907,7 @@ static BOOL parse_ntfs_boot_sector(ntfs_volume *vol, const NTFS_BOOT_SECTOR *b) vol->serial_no = le64_to_cpu(b->volume_serial_number); ntfs_debug("vol->serial_no = 0x%llx", (unsigned long long)vol->serial_no); - return TRUE; + return true; } /** @@ -1000,9 +1000,9 @@ static void ntfs_setup_allocators(ntfs_volume *vol) * load_and_init_mft_mirror - load and setup the mft mirror inode for a volume * @vol: ntfs super block describing device whose mft mirror to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_and_init_mft_mirror(ntfs_volume *vol) +static bool load_and_init_mft_mirror(ntfs_volume *vol) { struct inode *tmp_ino; ntfs_inode *tmp_ni; @@ -1014,7 +1014,7 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol) if (!IS_ERR(tmp_ino)) iput(tmp_ino); /* Caller will display error message. */ - return FALSE; + return false; } /* * Re-initialize some specifics about $MFTMirr's inode as @@ -1041,20 +1041,20 @@ static BOOL load_and_init_mft_mirror(ntfs_volume *vol) tmp_ni->itype.index.block_size_bits = vol->mft_record_size_bits; vol->mftmirr_ino = tmp_ino; ntfs_debug("Done."); - return TRUE; + return true; } /** * check_mft_mirror - compare contents of the mft mirror with the mft * @vol: ntfs super block describing device whose mft mirror to check * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. * * Note, this function also results in the mft mirror runlist being completely * mapped into memory. The mft mirror write code requires this and will BUG() * should it find an unmapped runlist element. */ -static BOOL check_mft_mirror(ntfs_volume *vol) +static bool check_mft_mirror(ntfs_volume *vol) { struct super_block *sb = vol->sb; ntfs_inode *mirr_ni; @@ -1086,7 +1086,7 @@ static BOOL check_mft_mirror(ntfs_volume *vol) index); if (IS_ERR(mft_page)) { ntfs_error(sb, "Failed to read $MFT."); - return FALSE; + return false; } kmft = page_address(mft_page); /* Get the $MFTMirr page. */ @@ -1110,7 +1110,7 @@ mm_unmap_out: ntfs_unmap_page(mirr_page); mft_unmap_out: ntfs_unmap_page(mft_page); - return FALSE; + return false; } } /* Do not check the mirror record if it is not in use. */ @@ -1169,21 +1169,21 @@ mft_unmap_out: ntfs_error(sb, "$MFTMirr location mismatch. " "Run chkdsk."); up_read(&mirr_ni->runlist.lock); - return FALSE; + return false; } } while (rl2[i++].length); up_read(&mirr_ni->runlist.lock); ntfs_debug("Done."); - return TRUE; + return true; } /** * load_and_check_logfile - load and check the logfile inode for a volume * @vol: ntfs super block describing device whose logfile to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_and_check_logfile(ntfs_volume *vol, +static bool load_and_check_logfile(ntfs_volume *vol, RESTART_PAGE_HEADER **rp) { struct inode *tmp_ino; @@ -1194,17 +1194,17 @@ static BOOL load_and_check_logfile(ntfs_volume *vol, if (!IS_ERR(tmp_ino)) iput(tmp_ino); /* Caller will display error message. */ - return FALSE; + return false; } if (!ntfs_check_logfile(tmp_ino, rp)) { iput(tmp_ino); /* ntfs_check_logfile() will have displayed error output. */ - return FALSE; + return false; } NInoSetSparseDisabled(NTFS_I(tmp_ino)); vol->logfile_ino = tmp_ino; ntfs_debug("Done."); - return TRUE; + return true; } #define NTFS_HIBERFIL_HEADER_SIZE 4096 @@ -1329,10 +1329,10 @@ iput_out: * load_and_init_quota - load and setup the quota file for a volume if present * @vol: ntfs super block describing device whose quota file to load * - * Return TRUE on success or FALSE on error. If $Quota is not present, we + * Return 'true' on success or 'false' on error. If $Quota is not present, we * leave vol->quota_ino as NULL and return success. */ -static BOOL load_and_init_quota(ntfs_volume *vol) +static bool load_and_init_quota(ntfs_volume *vol) { MFT_REF mref; struct inode *tmp_ino; @@ -1366,11 +1366,11 @@ static BOOL load_and_init_quota(ntfs_volume *vol) * not enabled. */ NVolSetQuotaOutOfDate(vol); - return TRUE; + return true; } /* A real error occured. */ ntfs_error(vol->sb, "Failed to find inode number for $Quota."); - return FALSE; + return false; } /* We do not care for the type of match that was found. */ kfree(name); @@ -1380,25 +1380,25 @@ static BOOL load_and_init_quota(ntfs_volume *vol) if (!IS_ERR(tmp_ino)) iput(tmp_ino); ntfs_error(vol->sb, "Failed to load $Quota."); - return FALSE; + return false; } vol->quota_ino = tmp_ino; /* Get the $Q index allocation attribute. */ tmp_ino = ntfs_index_iget(vol->quota_ino, Q, 2); if (IS_ERR(tmp_ino)) { ntfs_error(vol->sb, "Failed to load $Quota/$Q index."); - return FALSE; + return false; } vol->quota_q_ino = tmp_ino; ntfs_debug("Done."); - return TRUE; + return true; } /** * load_and_init_usnjrnl - load and setup the transaction log if present * @vol: ntfs super block describing device whose usnjrnl file to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. * * If $UsnJrnl is not present or in the process of being disabled, we set * NVolUsnJrnlStamped() and return success. @@ -1408,7 +1408,7 @@ static BOOL load_and_init_quota(ntfs_volume *vol) * stamped and nothing has been logged since, we also set NVolUsnJrnlStamped() * and return success. */ -static BOOL load_and_init_usnjrnl(ntfs_volume *vol) +static bool load_and_init_usnjrnl(ntfs_volume *vol) { MFT_REF mref; struct inode *tmp_ino; @@ -1450,12 +1450,12 @@ not_enabled: * transaction logging is not enabled. */ NVolSetUsnJrnlStamped(vol); - return TRUE; + return true; } /* A real error occured. */ ntfs_error(vol->sb, "Failed to find inode number for " "$UsnJrnl."); - return FALSE; + return false; } /* We do not care for the type of match that was found. */ kfree(name); @@ -1465,7 +1465,7 @@ not_enabled: if (!IS_ERR(tmp_ino)) iput(tmp_ino); ntfs_error(vol->sb, "Failed to load $UsnJrnl."); - return FALSE; + return false; } vol->usnjrnl_ino = tmp_ino; /* @@ -1483,7 +1483,7 @@ not_enabled: if (IS_ERR(tmp_ino)) { ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$Max " "attribute."); - return FALSE; + return false; } vol->usnjrnl_max_ino = tmp_ino; if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) { @@ -1491,14 +1491,14 @@ not_enabled: "attribute (size is 0x%llx but should be at " "least 0x%zx bytes).", i_size_read(tmp_ino), sizeof(USN_HEADER)); - return FALSE; + return false; } /* Get the $DATA/$J attribute. */ tmp_ino = ntfs_attr_iget(vol->usnjrnl_ino, AT_DATA, J, 2); if (IS_ERR(tmp_ino)) { ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$J " "attribute."); - return FALSE; + return false; } vol->usnjrnl_j_ino = tmp_ino; /* Verify $J is non-resident and sparse. */ @@ -1506,14 +1506,14 @@ not_enabled: if (unlikely(!NInoNonResident(tmp_ni) || !NInoSparse(tmp_ni))) { ntfs_error(vol->sb, "$UsnJrnl/$DATA/$J attribute is resident " "and/or not sparse."); - return FALSE; + return false; } /* Read the USN_HEADER from $DATA/$Max. */ page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0); if (IS_ERR(page)) { ntfs_error(vol->sb, "Failed to read from $UsnJrnl/$DATA/$Max " "attribute."); - return FALSE; + return false; } uh = (USN_HEADER*)page_address(page); /* Sanity check the $Max. */ @@ -1524,7 +1524,7 @@ not_enabled: (long long)sle64_to_cpu(uh->allocation_delta), (long long)sle64_to_cpu(uh->maximum_size)); ntfs_unmap_page(page); - return FALSE; + return false; } /* * If the transaction log has been stamped and nothing has been written @@ -1548,20 +1548,20 @@ not_enabled: (long long)sle64_to_cpu(uh->lowest_valid_usn), i_size_read(vol->usnjrnl_j_ino)); ntfs_unmap_page(page); - return FALSE; + return false; } ntfs_unmap_page(page); ntfs_debug("Done."); - return TRUE; + return true; } /** * load_and_init_attrdef - load the attribute definitions table for a volume * @vol: ntfs super block describing device whose attrdef to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_and_init_attrdef(ntfs_volume *vol) +static bool load_and_init_attrdef(ntfs_volume *vol) { loff_t i_size; struct super_block *sb = vol->sb; @@ -1607,7 +1607,7 @@ read_partial_attrdef_page: vol->attrdef_size = i_size; ntfs_debug("Read %llu bytes from $AttrDef.", i_size); iput(ino); - return TRUE; + return true; free_iput_failed: ntfs_free(vol->attrdef); vol->attrdef = NULL; @@ -1615,7 +1615,7 @@ iput_failed: iput(ino); failed: ntfs_error(sb, "Failed to initialize attribute definition table."); - return FALSE; + return false; } #endif /* NTFS_RW */ @@ -1624,9 +1624,9 @@ failed: * load_and_init_upcase - load the upcase table for an ntfs volume * @vol: ntfs super block describing device whose upcase to load * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_and_init_upcase(ntfs_volume *vol) +static bool load_and_init_upcase(ntfs_volume *vol) { loff_t i_size; struct super_block *sb = vol->sb; @@ -1682,7 +1682,7 @@ read_partial_upcase_page: ntfs_debug("Using volume specified $UpCase since default is " "not present."); mutex_unlock(&ntfs_lock); - return TRUE; + return true; } max = default_upcase_len; if (max > vol->upcase_len) @@ -1698,12 +1698,12 @@ read_partial_upcase_page: mutex_unlock(&ntfs_lock); ntfs_debug("Volume specified $UpCase matches default. Using " "default."); - return TRUE; + return true; } mutex_unlock(&ntfs_lock); ntfs_debug("Using volume specified $UpCase since it does not match " "the default."); - return TRUE; + return true; iput_upcase_failed: iput(ino); ntfs_free(vol->upcase); @@ -1717,11 +1717,11 @@ upcase_failed: mutex_unlock(&ntfs_lock); ntfs_error(sb, "Failed to load $UpCase from the volume. Using " "default."); - return TRUE; + return true; } mutex_unlock(&ntfs_lock); ntfs_error(sb, "Failed to initialize upcase table."); - return FALSE; + return false; } /* @@ -1739,9 +1739,9 @@ static struct lock_class_key * Open the system files with normal access functions and complete setting up * the ntfs super block @vol. * - * Return TRUE on success or FALSE on error. + * Return 'true' on success or 'false' on error. */ -static BOOL load_system_files(ntfs_volume *vol) +static bool load_system_files(ntfs_volume *vol) { struct super_block *sb = vol->sb; MFT_RECORD *m; @@ -2067,7 +2067,7 @@ get_ctx_vol_failed: #endif /* NTFS_RW */ /* If on NTFS versions before 3.0, we are done. */ if (unlikely(vol->major_ver < 3)) - return TRUE; + return true; /* NTFS 3.0+ specific initialization. */ /* Get the security descriptors inode. */ vol->secure_ino = ntfs_iget(sb, FILE_Secure); @@ -2173,7 +2173,7 @@ get_ctx_vol_failed: NVolSetErrors(vol); } #endif /* NTFS_RW */ - return TRUE; + return true; #ifdef NTFS_RW iput_usnjrnl_err_out: if (vol->usnjrnl_j_ino) @@ -2229,7 +2229,7 @@ iput_mirr_err_out: if (vol->mftmirr_ino) iput(vol->mftmirr_ino); #endif /* NTFS_RW */ - return FALSE; + return false; } /** diff --git a/fs/ntfs/types.h b/fs/ntfs/types.h index 6e4a7e3343f..8c8053b6698 100644 --- a/fs/ntfs/types.h +++ b/fs/ntfs/types.h @@ -61,11 +61,6 @@ typedef sle64 leLSN; typedef s64 USN; typedef sle64 leUSN; -typedef enum { - FALSE = 0, - TRUE = 1 -} BOOL; - typedef enum { CASE_SENSITIVE = 0, IGNORE_CASE = 1, diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c index a1b572196fe..6a495f7369f 100644 --- a/fs/ntfs/unistr.c +++ b/fs/ntfs/unistr.c @@ -61,16 +61,16 @@ static const u8 legal_ansi_char_array[0x40] = { * @upcase: upcase table (only if @ic == IGNORE_CASE) * @upcase_size: length in Unicode characters of @upcase (if present) * - * Compare the names @s1 and @s2 and return TRUE (1) if the names are - * identical, or FALSE (0) if they are not identical. If @ic is IGNORE_CASE, + * Compare the names @s1 and @s2 and return 'true' (1) if the names are + * identical, or 'false' (0) if they are not identical. If @ic is IGNORE_CASE, * the @upcase table is used to performa a case insensitive comparison. */ -BOOL ntfs_are_names_equal(const ntfschar *s1, size_t s1_len, +bool ntfs_are_names_equal(const ntfschar *s1, size_t s1_len, const ntfschar *s2, size_t s2_len, const IGNORE_CASE_BOOL ic, const ntfschar *upcase, const u32 upcase_size) { if (s1_len != s2_len) - return FALSE; + return false; if (ic == CASE_SENSITIVE) return !ntfs_ucsncmp(s1, s2, s1_len); return !ntfs_ucsncasecmp(s1, s2, s1_len, upcase, upcase_size); diff --git a/fs/ntfs/usnjrnl.c b/fs/ntfs/usnjrnl.c index 77773240d13..b2bc0d55b03 100644 --- a/fs/ntfs/usnjrnl.c +++ b/fs/ntfs/usnjrnl.c @@ -39,12 +39,12 @@ * @vol: ntfs volume on which to stamp the transaction log * * Stamp the transaction log ($UsnJrnl) on the ntfs volume @vol and return - * TRUE on success and FALSE on error. + * 'true' on success and 'false' on error. * * This function assumes that the transaction log has already been loaded and * consistency checked by a call to fs/ntfs/super.c::load_and_init_usnjrnl(). */ -BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol) +bool ntfs_stamp_usnjrnl(ntfs_volume *vol) { ntfs_debug("Entering."); if (likely(!NVolUsnJrnlStamped(vol))) { @@ -56,7 +56,7 @@ BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol) if (IS_ERR(page)) { ntfs_error(vol->sb, "Failed to read from " "$UsnJrnl/$DATA/$Max attribute."); - return FALSE; + return false; } uh = (USN_HEADER*)page_address(page); stamp = get_current_ntfs_time(); @@ -78,7 +78,7 @@ BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol) NVolSetUsnJrnlStamped(vol); } ntfs_debug("Done."); - return TRUE; + return true; } #endif /* NTFS_RW */ diff --git a/fs/ntfs/usnjrnl.h b/fs/ntfs/usnjrnl.h index ff988b0deb4..3a8af75351e 100644 --- a/fs/ntfs/usnjrnl.h +++ b/fs/ntfs/usnjrnl.h @@ -198,7 +198,7 @@ typedef struct { /* sizeof() = 60 (0x3c) bytes */ } __attribute__ ((__packed__)) USN_RECORD; -extern BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol); +extern bool ntfs_stamp_usnjrnl(ntfs_volume *vol); #endif /* NTFS_RW */ -- cgit v1.2.3 From 4d81715fc5dfa1680ad47d7edf3ac4a74c5bf104 Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Sat, 30 Sep 2006 23:27:14 -0700 Subject: [PATCH] fs/jfs: Conversion to generic boolean Conversion of booleans to: generic-boolean.patch (2006-08-23) Signed-off-by: Richard Knutsson Cc: Dave Kleikamp Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/jfs/inode.c | 2 +- fs/jfs/jfs_dmap.c | 12 ++++++------ fs/jfs/jfs_extent.c | 14 +++++++------- fs/jfs/jfs_extent.h | 4 ++-- fs/jfs/jfs_imap.c | 26 +++++++++++++------------- fs/jfs/jfs_imap.h | 4 ++-- fs/jfs/jfs_metapage.h | 4 ++-- fs/jfs/jfs_txnmgr.c | 16 ++++++++-------- fs/jfs/jfs_types.h | 4 ---- fs/jfs/jfs_xtree.c | 2 +- fs/jfs/xattr.c | 10 +++++----- 11 files changed, 47 insertions(+), 51 deletions(-) (limited to 'fs') diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index a223cf4faa9..a8cc169235d 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -227,7 +227,7 @@ int jfs_get_block(struct inode *ip, sector_t lblock, #ifdef _JFS_4K if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) goto unlock; - rc = extAlloc(ip, xlen, lblock64, &xad, FALSE); + rc = extAlloc(ip, xlen, lblock64, &xad, false); if (rc) goto unlock; diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index c161c98954e..f05ebb62918 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -403,8 +403,8 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks) * * PARAMETERS: * ipbmap - pointer to in-core inode for the block map. - * free - TRUE if block range is to be freed from the persistent - * map; FALSE if it is to be allocated. + * free - 'true' if block range is to be freed from the persistent + * map; 'false' if it is to be allocated. * blkno - starting block number of the range. * nblocks - number of contiguous blocks in the range. * tblk - transaction block; @@ -2394,7 +2394,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, * requires the dmap control page to be adjusted. * newval - the new value of the lower level dmap or dmap control * page root. - * alloc - TRUE if adjustment is due to an allocation. + * alloc - 'true' if adjustment is due to an allocation. * level - current level of dmap control page (i.e. L0, L1, L2) to * be adjusted. * @@ -3290,7 +3290,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) { struct jfs_sb_info *sbi = JFS_SBI(ipbmap->i_sb); int nbperpage = sbi->nbperpage; - int i, i0 = TRUE, j, j0 = TRUE, k, n; + int i, i0 = true, j, j0 = true, k, n; s64 newsize; s64 p; struct metapage *mp, *l2mp, *l1mp = NULL, *l0mp = NULL; @@ -3398,7 +3398,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) j = (blkno & (MAXL1SIZE - 1)) >> L2MAXL0SIZE; l1leaf = l1dcp->stree + CTLLEAFIND + j; p = BLKTOL0(blkno, sbi->l2nbperpage); - j0 = FALSE; + j0 = false; } else { /* assign/init L1 page */ l1mp = get_metapage(ipbmap, p, PSIZE, 0); @@ -3432,7 +3432,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks) l0leaf = l0dcp->stree + CTLLEAFIND + i; p = BLKTODMAP(blkno, sbi->l2nbperpage); - i0 = FALSE; + i0 = false; } else { /* assign/init L0 page */ l0mp = get_metapage(ipbmap, p, PSIZE, 0); diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c index 4c74f0944f7..933b7457bfb 100644 --- a/fs/jfs/jfs_extent.c +++ b/fs/jfs/jfs_extent.c @@ -74,7 +74,7 @@ static s64 extRoundDown(s64 nb); * extent that is used as an allocation hint if the * xaddr of the xad is non-zero. on successful exit, * the xad describes the newly allocated extent. - * abnr - boolean_t indicating whether the newly allocated extent + * abnr - bool indicating whether the newly allocated extent * should be marked as allocated but not recorded. * * RETURN VALUES: @@ -83,7 +83,7 @@ static s64 extRoundDown(s64 nb); * -ENOSPC - insufficient disk resources. */ int -extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) +extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) { struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb); s64 nxlen, nxaddr, xoff, hint, xaddr = 0; @@ -117,7 +117,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) * following the hint extent. */ if (offsetXAD(xp) + nxlen == xoff && - abnr == ((xp->flag & XAD_NOTRECORDED) ? TRUE : FALSE)) + abnr == ((xp->flag & XAD_NOTRECORDED) ? true : false)) xaddr = hint + nxlen; /* adjust the hint to the last block of the extent */ @@ -148,7 +148,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) } /* determine the value of the extent flag */ - xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0; + xflag = abnr ? XAD_NOTRECORDED : 0; /* if we can extend the hint extent to cover the current request, * extend it. otherwise, insert a new extent to @@ -203,7 +203,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) * xlen - request size of the resulting extent. * xp - pointer to an xad. on successful exit, the xad * describes the newly allocated extent. - * abnr - boolean_t indicating whether the newly allocated extent + * abnr - bool indicating whether the newly allocated extent * should be marked as allocated but not recorded. * * RETURN VALUES: @@ -211,7 +211,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) * -EIO - i/o error. * -ENOSPC - insufficient disk resources. */ -int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) +int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) { struct super_block *sb = ip->i_sb; s64 xaddr, xlen, nxaddr, delta, xoff; @@ -476,7 +476,7 @@ int extFill(struct inode *ip, xad_t * xp) XADaddress(xp, 0); /* allocate an extent to fill the hole */ - if ((rc = extAlloc(ip, nbperpage, blkno, xp, FALSE))) + if ((rc = extAlloc(ip, nbperpage, blkno, xp, false))) return (rc); assert(lengthPXD(xp) == nbperpage); diff --git a/fs/jfs/jfs_extent.h b/fs/jfs/jfs_extent.h index e80fc7ced87..3a7f3f22e98 100644 --- a/fs/jfs/jfs_extent.h +++ b/fs/jfs/jfs_extent.h @@ -22,10 +22,10 @@ #define INOHINT(ip) \ (addressPXD(&(JFS_IP(ip)->ixpxd)) + lengthPXD(&(JFS_IP(ip)->ixpxd)) - 1) -extern int extAlloc(struct inode *, s64, s64, xad_t *, boolean_t); +extern int extAlloc(struct inode *, s64, s64, xad_t *, bool); extern int extFill(struct inode *, xad_t *); extern int extHint(struct inode *, s64, xad_t *); -extern int extRealloc(struct inode *, s64, xad_t *, boolean_t); +extern int extRealloc(struct inode *, s64, xad_t *, bool); extern int extRecord(struct inode *, xad_t *); #endif /* _H_JFS_EXTENT */ diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 369d7f39c04..a45ee248958 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -78,8 +78,8 @@ static HLIST_HEAD(aggregate_hash); /* * forward references */ -static int diAllocAG(struct inomap *, int, boolean_t, struct inode *); -static int diAllocAny(struct inomap *, int, boolean_t, struct inode *); +static int diAllocAG(struct inomap *, int, bool, struct inode *); +static int diAllocAny(struct inomap *, int, bool, struct inode *); static int diAllocBit(struct inomap *, struct iag *, int); static int diAllocExt(struct inomap *, int, struct inode *); static int diAllocIno(struct inomap *, int, struct inode *); @@ -1345,7 +1345,7 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) * * PARAMETERS: * pip - pointer to incore inode for the parent inode. - * dir - TRUE if the new disk inode is for a directory. + * dir - 'true' if the new disk inode is for a directory. * ip - pointer to a new inode * * RETURN VALUES: @@ -1353,7 +1353,7 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) * -ENOSPC - insufficient disk resources. * -EIO - i/o error. */ -int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) +int diAlloc(struct inode *pip, bool dir, struct inode *ip) { int rc, ino, iagno, addext, extno, bitno, sword; int nwords, rem, i, agno; @@ -1375,7 +1375,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) /* for a directory, the allocation policy is to start * at the ag level using the preferred ag. */ - if (dir == TRUE) { + if (dir) { agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap); AG_LOCK(imap, agno); goto tryag; @@ -1651,7 +1651,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) * PARAMETERS: * imap - pointer to inode map control structure. * agno - allocation group to allocate from. - * dir - TRUE if the new disk inode is for a directory. + * dir - 'true' if the new disk inode is for a directory. * ip - pointer to the new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. @@ -1662,7 +1662,7 @@ int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip) * -EIO - i/o error. */ static int -diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) +diAllocAG(struct inomap * imap, int agno, bool dir, struct inode *ip) { int rc, addext, numfree, numinos; @@ -1682,7 +1682,7 @@ diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) * if there are a small number of free inodes or number of free * inodes is a small percentage of the number of backed inodes. */ - if (dir == TRUE) + if (dir) addext = (numfree < 64 || (numfree < 256 && ((numfree * 100) / numinos) <= 20)); @@ -1721,7 +1721,7 @@ diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) * PARAMETERS: * imap - pointer to inode map control structure. * agno - primary allocation group (to avoid). - * dir - TRUE if the new disk inode is for a directory. + * dir - 'true' if the new disk inode is for a directory. * ip - pointer to a new inode to be filled in on successful return * with the disk inode number allocated, its extent address * and the start of the ag. @@ -1732,7 +1732,7 @@ diAllocAG(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) * -EIO - i/o error. */ static int -diAllocAny(struct inomap * imap, int agno, boolean_t dir, struct inode *ip) +diAllocAny(struct inomap * imap, int agno, bool dir, struct inode *ip) { int ag, rc; int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag; @@ -2749,7 +2749,7 @@ static int diFindFree(u32 word, int start) * PARAMETERS: * ipimap - Incore inode map inode * inum - Number of inode to mark in permanent map - * is_free - If TRUE indicates inode should be marked freed, otherwise + * is_free - If 'true' indicates inode should be marked freed, otherwise * indicates inode should be marked allocated. * * RETURN VALUES: @@ -2757,7 +2757,7 @@ static int diFindFree(u32 word, int start) */ int diUpdatePMap(struct inode *ipimap, - unsigned long inum, boolean_t is_free, struct tblock * tblk) + unsigned long inum, bool is_free, struct tblock * tblk) { int rc; struct iag *iagp; @@ -2796,7 +2796,7 @@ diUpdatePMap(struct inode *ipimap, /* * mark the inode free in persistent map: */ - if (is_free == TRUE) { + if (is_free) { /* The inode should have been allocated both in working * map and in persistent map; * the inode will be freed from working map at the release diff --git a/fs/jfs/jfs_imap.h b/fs/jfs/jfs_imap.h index 6e24465f0f9..e3b7db47db6 100644 --- a/fs/jfs/jfs_imap.h +++ b/fs/jfs/jfs_imap.h @@ -159,11 +159,11 @@ struct inomap { #define im_maxag im_imap.in_maxag extern int diFree(struct inode *); -extern int diAlloc(struct inode *, boolean_t, struct inode *); +extern int diAlloc(struct inode *, bool, struct inode *); extern int diSync(struct inode *); /* external references */ extern int diUpdatePMap(struct inode *ipimap, unsigned long inum, - boolean_t is_free, struct tblock * tblk); + bool is_free, struct tblock * tblk); extern int diExtendFS(struct inode *ipimap, struct inode *ipbmap); extern int diMount(struct inode *); extern int diUnmount(struct inode *, int); diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h index d17a3290f5a..01a5a455e01 100644 --- a/fs/jfs/jfs_metapage.h +++ b/fs/jfs/jfs_metapage.h @@ -65,10 +65,10 @@ extern struct metapage *__get_metapage(struct inode *inode, int absolute, unsigned long new); #define read_metapage(inode, lblock, size, absolute)\ - __get_metapage(inode, lblock, size, absolute, FALSE) + __get_metapage(inode, lblock, size, absolute, false) #define get_metapage(inode, lblock, size, absolute)\ - __get_metapage(inode, lblock, size, absolute, TRUE) + __get_metapage(inode, lblock, size, absolute, true) extern void release_metapage(struct metapage *); extern void grab_metapage(struct metapage *); diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 3856efc399c..ebfa6c061d7 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -2393,7 +2393,7 @@ static void txUpdateMap(struct tblock * tblk) * unlock mapper/write lock */ if (tblk->xflag & COMMIT_CREATE) { - diUpdatePMap(ipimap, tblk->ino, FALSE, tblk); + diUpdatePMap(ipimap, tblk->ino, false, tblk); /* update persistent block allocation map * for the allocation of inode extent; */ @@ -2403,7 +2403,7 @@ static void txUpdateMap(struct tblock * tblk) txAllocPMap(ipimap, (struct maplock *) & pxdlock, tblk); } else if (tblk->xflag & COMMIT_DELETE) { ip = tblk->u.ip; - diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk); + diUpdatePMap(ipimap, ip->i_ino, true, tblk); iput(ip); } } @@ -2451,7 +2451,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, if (xad->flag & (XAD_NEW | XAD_EXTENDED)) { xaddr = addressXAD(xad); xlen = lengthXAD(xad); - dbUpdatePMap(ipbmap, FALSE, xaddr, + dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen, tblk); xad->flag &= ~(XAD_NEW | XAD_EXTENDED); jfs_info("allocPMap: xaddr:0x%lx xlen:%d", @@ -2462,7 +2462,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, pxdlock = (struct pxd_lock *) maplock; xaddr = addressPXD(&pxdlock->pxd); xlen = lengthPXD(&pxdlock->pxd); - dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk); + dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen, tblk); jfs_info("allocPMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); } else { /* (maplock->flag & mlckALLOCPXDLIST) */ @@ -2471,7 +2471,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock, for (n = 0; n < pxdlistlock->count; n++, pxd++) { xaddr = addressPXD(pxd); xlen = lengthPXD(pxd); - dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, + dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen, tblk); jfs_info("allocPMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); @@ -2513,7 +2513,7 @@ void txFreeMap(struct inode *ip, if (!(xad->flag & XAD_NEW)) { xaddr = addressXAD(xad); xlen = lengthXAD(xad); - dbUpdatePMap(ipbmap, TRUE, xaddr, + dbUpdatePMap(ipbmap, true, xaddr, (s64) xlen, tblk); jfs_info("freePMap: xaddr:0x%lx " "xlen:%d", @@ -2524,7 +2524,7 @@ void txFreeMap(struct inode *ip, pxdlock = (struct pxd_lock *) maplock; xaddr = addressPXD(&pxdlock->pxd); xlen = lengthPXD(&pxdlock->pxd); - dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen, + dbUpdatePMap(ipbmap, true, xaddr, (s64) xlen, tblk); jfs_info("freePMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); @@ -2535,7 +2535,7 @@ void txFreeMap(struct inode *ip, for (n = 0; n < pxdlistlock->count; n++, pxd++) { xaddr = addressPXD(pxd); xlen = lengthPXD(pxd); - dbUpdatePMap(ipbmap, TRUE, xaddr, + dbUpdatePMap(ipbmap, true, xaddr, (s64) xlen, tblk); jfs_info("freePMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen); diff --git a/fs/jfs/jfs_types.h b/fs/jfs/jfs_types.h index 5bfad39a207..09b25295868 100644 --- a/fs/jfs/jfs_types.h +++ b/fs/jfs/jfs_types.h @@ -57,10 +57,6 @@ struct timestruc_t { #define HIGHORDER 0x80000000u /* high order bit on */ #define ONES 0xffffffffu /* all bit on */ -typedef int boolean_t; -#define TRUE 1 -#define FALSE 0 - /* * logical xd (lxd) */ diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index e72f4ebb6e9..c92307d3a57 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c @@ -2964,7 +2964,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */ cmSetXD(ip, cp, pno, dxaddr, nblks); /* release the cbuf, mark it as modified */ - cmPut(cp, TRUE); + cmPut(cp, true); dxaddr += nblks; sxaddr += nblks; diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 9bc5b7c055c..7a10e192896 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -97,26 +97,26 @@ static inline int is_os2_xattr(struct jfs_ea *ea) */ if ((ea->namelen >= XATTR_SYSTEM_PREFIX_LEN) && !strncmp(ea->name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) - return FALSE; + return false; /* * Check for "user." */ if ((ea->namelen >= XATTR_USER_PREFIX_LEN) && !strncmp(ea->name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) - return FALSE; + return false; /* * Check for "security." */ if ((ea->namelen >= XATTR_SECURITY_PREFIX_LEN) && !strncmp(ea->name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) - return FALSE; + return false; /* * Check for "trusted." */ if ((ea->namelen >= XATTR_TRUSTED_PREFIX_LEN) && !strncmp(ea->name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) - return FALSE; + return false; /* * Add any other valid namespace prefixes here */ @@ -124,7 +124,7 @@ static inline int is_os2_xattr(struct jfs_ea *ea) /* * We assume it's OS/2's flat namespace */ - return TRUE; + return true; } static inline int name_size(struct jfs_ea *ea) -- cgit v1.2.3 From 130c6b98984a058068ea595c465fba2beb48b9ef Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Sat, 30 Sep 2006 23:27:15 -0700 Subject: [PATCH] fs/partitions: Conversion to generic boolean Conversion of booleans to: generic-boolean.patch (2006-08-23) Signed-off-by: Richard Knutsson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/partitions/ldm.c | 267 ++++++++++++++++++++++++++-------------------------- 1 file changed, 131 insertions(+), 136 deletions(-) (limited to 'fs') diff --git a/fs/partitions/ldm.c b/fs/partitions/ldm.c index 7ab1c11dca4..1a60926a4cc 100644 --- a/fs/partitions/ldm.c +++ b/fs/partitions/ldm.c @@ -30,11 +30,6 @@ #include "check.h" #include "msdos.h" -typedef enum { - FALSE = 0, - TRUE = 1 -} BOOL; - /** * ldm_debug/info/error/crit - Output an error message * @f: A printf format string containing the message @@ -103,24 +98,24 @@ static int ldm_parse_hexbyte (const u8 *src) * * N.B. The GUID need not be NULL terminated. * - * Return: TRUE @dest contains binary GUID - * FALSE @dest contents are undefined + * Return: 'true' @dest contains binary GUID + * 'false' @dest contents are undefined */ -static BOOL ldm_parse_guid (const u8 *src, u8 *dest) +static bool ldm_parse_guid (const u8 *src, u8 *dest) { static const int size[] = { 4, 2, 2, 2, 6 }; int i, j, v; if (src[8] != '-' || src[13] != '-' || src[18] != '-' || src[23] != '-') - return FALSE; + return false; for (j = 0; j < 5; j++, src++) for (i = 0; i < size[j]; i++, src+=2, *dest++ = v) if ((v = ldm_parse_hexbyte (src)) < 0) - return FALSE; + return false; - return TRUE; + return true; } @@ -132,17 +127,17 @@ static BOOL ldm_parse_guid (const u8 *src, u8 *dest) * This parses the LDM database PRIVHEAD structure supplied in @data and * sets up the in-memory privhead structure @ph with the obtained information. * - * Return: TRUE @ph contains the PRIVHEAD data - * FALSE @ph contents are undefined + * Return: 'true' @ph contains the PRIVHEAD data + * 'false' @ph contents are undefined */ -static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph) +static bool ldm_parse_privhead (const u8 *data, struct privhead *ph) { BUG_ON (!data || !ph); if (MAGIC_PRIVHEAD != BE64 (data)) { ldm_error ("Cannot find PRIVHEAD structure. LDM database is" " corrupt. Aborting."); - return FALSE; + return false; } ph->ver_major = BE16 (data + 0x000C); @@ -155,7 +150,7 @@ static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph) if ((ph->ver_major != 2) || (ph->ver_minor != 11)) { ldm_error ("Expected PRIVHEAD version %d.%d, got %d.%d." " Aborting.", 2, 11, ph->ver_major, ph->ver_minor); - return FALSE; + return false; } if (ph->config_size != LDM_DB_SIZE) { /* 1 MiB in sectors. */ /* Warn the user and continue, carefully */ @@ -166,16 +161,16 @@ static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph) if ((ph->logical_disk_size == 0) || (ph->logical_disk_start + ph->logical_disk_size > ph->config_start)) { ldm_error ("PRIVHEAD disk size doesn't match real disk size"); - return FALSE; + return false; } if (!ldm_parse_guid (data + 0x0030, ph->disk_id)) { ldm_error ("PRIVHEAD contains an invalid GUID."); - return FALSE; + return false; } ldm_debug ("Parsed PRIVHEAD successfully."); - return TRUE; + return true; } /** @@ -189,16 +184,16 @@ static BOOL ldm_parse_privhead (const u8 *data, struct privhead *ph) * * N.B. The *_start and *_size values returned in @toc are not range-checked. * - * Return: TRUE @toc contains the TOCBLOCK data - * FALSE @toc contents are undefined + * Return: 'true' @toc contains the TOCBLOCK data + * 'false' @toc contents are undefined */ -static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc) +static bool ldm_parse_tocblock (const u8 *data, struct tocblock *toc) { BUG_ON (!data || !toc); if (MAGIC_TOCBLOCK != BE64 (data)) { ldm_crit ("Cannot find TOCBLOCK, database may be corrupt."); - return FALSE; + return false; } strncpy (toc->bitmap1_name, data + 0x24, sizeof (toc->bitmap1_name)); toc->bitmap1_name[sizeof (toc->bitmap1_name) - 1] = 0; @@ -209,7 +204,7 @@ static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc) sizeof (toc->bitmap1_name)) != 0) { ldm_crit ("TOCBLOCK's first bitmap is '%s', should be '%s'.", TOC_BITMAP1, toc->bitmap1_name); - return FALSE; + return false; } strncpy (toc->bitmap2_name, data + 0x46, sizeof (toc->bitmap2_name)); toc->bitmap2_name[sizeof (toc->bitmap2_name) - 1] = 0; @@ -219,10 +214,10 @@ static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc) sizeof (toc->bitmap2_name)) != 0) { ldm_crit ("TOCBLOCK's second bitmap is '%s', should be '%s'.", TOC_BITMAP2, toc->bitmap2_name); - return FALSE; + return false; } ldm_debug ("Parsed TOCBLOCK successfully."); - return TRUE; + return true; } /** @@ -235,16 +230,16 @@ static BOOL ldm_parse_tocblock (const u8 *data, struct tocblock *toc) * * N.B. The *_start, *_size and *_seq values will be range-checked later. * - * Return: TRUE @vm contains VMDB info - * FALSE @vm contents are undefined + * Return: 'true' @vm contains VMDB info + * 'false' @vm contents are undefined */ -static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm) +static bool ldm_parse_vmdb (const u8 *data, struct vmdb *vm) { BUG_ON (!data || !vm); if (MAGIC_VMDB != BE32 (data)) { ldm_crit ("Cannot find the VMDB, database may be corrupt."); - return FALSE; + return false; } vm->ver_major = BE16 (data + 0x12); @@ -252,7 +247,7 @@ static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm) if ((vm->ver_major != 4) || (vm->ver_minor != 10)) { ldm_error ("Expected VMDB version %d.%d, got %d.%d. " "Aborting.", 4, 10, vm->ver_major, vm->ver_minor); - return FALSE; + return false; } vm->vblk_size = BE32 (data + 0x08); @@ -260,7 +255,7 @@ static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm) vm->last_vblk_seq = BE32 (data + 0x04); ldm_debug ("Parsed VMDB successfully."); - return TRUE; + return true; } /** @@ -270,10 +265,10 @@ static BOOL ldm_parse_vmdb (const u8 *data, struct vmdb *vm) * * This compares the two privhead structures @ph1 and @ph2. * - * Return: TRUE Identical - * FALSE Different + * Return: 'true' Identical + * 'false' Different */ -static BOOL ldm_compare_privheads (const struct privhead *ph1, +static bool ldm_compare_privheads (const struct privhead *ph1, const struct privhead *ph2) { BUG_ON (!ph1 || !ph2); @@ -294,10 +289,10 @@ static BOOL ldm_compare_privheads (const struct privhead *ph1, * * This compares the two tocblock structures @toc1 and @toc2. * - * Return: TRUE Identical - * FALSE Different + * Return: 'true' Identical + * 'false' Different */ -static BOOL ldm_compare_tocblocks (const struct tocblock *toc1, +static bool ldm_compare_tocblocks (const struct tocblock *toc1, const struct tocblock *toc2) { BUG_ON (!toc1 || !toc2); @@ -323,17 +318,17 @@ static BOOL ldm_compare_tocblocks (const struct tocblock *toc1, * the configuration area (the database). The values are range-checked against * @hd, which contains the real size of the disk. * - * Return: TRUE Success - * FALSE Error + * Return: 'true' Success + * 'false' Error */ -static BOOL ldm_validate_privheads (struct block_device *bdev, +static bool ldm_validate_privheads (struct block_device *bdev, struct privhead *ph1) { static const int off[3] = { OFF_PRIV1, OFF_PRIV2, OFF_PRIV3 }; struct privhead *ph[3] = { ph1 }; Sector sect; u8 *data; - BOOL result = FALSE; + bool result = false; long num_sects; int i; @@ -393,7 +388,7 @@ static BOOL ldm_validate_privheads (struct block_device *bdev, goto out; }*/ ldm_debug ("Validated PRIVHEADs successfully."); - result = TRUE; + result = true; out: kfree (ph[1]); kfree (ph[2]); @@ -411,10 +406,10 @@ out: * * The offsets and sizes of the configs are range-checked against a privhead. * - * Return: TRUE @toc1 contains validated TOCBLOCK info - * FALSE @toc1 contents are undefined + * Return: 'true' @toc1 contains validated TOCBLOCK info + * 'false' @toc1 contents are undefined */ -static BOOL ldm_validate_tocblocks (struct block_device *bdev, +static bool ldm_validate_tocblocks (struct block_device *bdev, unsigned long base, struct ldmdb *ldb) { static const int off[4] = { OFF_TOCB1, OFF_TOCB2, OFF_TOCB3, OFF_TOCB4}; @@ -422,7 +417,7 @@ static BOOL ldm_validate_tocblocks (struct block_device *bdev, struct privhead *ph; Sector sect; u8 *data; - BOOL result = FALSE; + bool result = false; int i; BUG_ON (!bdev || !ldb); @@ -465,7 +460,7 @@ static BOOL ldm_validate_tocblocks (struct block_device *bdev, } ldm_debug ("Validated TOCBLOCKs successfully."); - result = TRUE; + result = true; out: kfree (tb[1]); kfree (tb[2]); @@ -482,15 +477,15 @@ out: * Find the vmdb of the LDM Database stored on @bdev and return the parsed * information in @ldb. * - * Return: TRUE @ldb contains validated VBDB info - * FALSE @ldb contents are undefined + * Return: 'true' @ldb contains validated VBDB info + * 'false' @ldb contents are undefined */ -static BOOL ldm_validate_vmdb (struct block_device *bdev, unsigned long base, +static bool ldm_validate_vmdb (struct block_device *bdev, unsigned long base, struct ldmdb *ldb) { Sector sect; u8 *data; - BOOL result = FALSE; + bool result = false; struct vmdb *vm; struct tocblock *toc; @@ -502,7 +497,7 @@ static BOOL ldm_validate_vmdb (struct block_device *bdev, unsigned long base, data = read_dev_sector (bdev, base + OFF_VMDB, §); if (!data) { ldm_crit ("Disk read failed."); - return FALSE; + return false; } if (!ldm_parse_vmdb (data, vm)) @@ -527,7 +522,7 @@ static BOOL ldm_validate_vmdb (struct block_device *bdev, unsigned long base, goto out; } - result = TRUE; + result = true; out: put_dev_sector (sect); return result; @@ -547,23 +542,23 @@ out: * only likely to happen if the underlying device is strange. If that IS * the case we should return zero to let someone else try. * - * Return: TRUE @bdev is a dynamic disk - * FALSE @bdev is not a dynamic disk, or an error occurred + * Return: 'true' @bdev is a dynamic disk + * 'false' @bdev is not a dynamic disk, or an error occurred */ -static BOOL ldm_validate_partition_table (struct block_device *bdev) +static bool ldm_validate_partition_table (struct block_device *bdev) { Sector sect; u8 *data; struct partition *p; int i; - BOOL result = FALSE; + bool result = false; BUG_ON (!bdev); data = read_dev_sector (bdev, 0, §); if (!data) { ldm_crit ("Disk read failed."); - return FALSE; + return false; } if (*(__le16*) (data + 0x01FE) != cpu_to_le16 (MSDOS_LABEL_MAGIC)) @@ -572,7 +567,7 @@ static BOOL ldm_validate_partition_table (struct block_device *bdev) p = (struct partition*)(data + 0x01BE); for (i = 0; i < 4; i++, p++) if (SYS_IND (p) == WIN2K_DYNAMIC_PARTITION) { - result = TRUE; + result = true; break; } @@ -625,10 +620,10 @@ static struct vblk * ldm_get_disk_objid (const struct ldmdb *ldb) * N.B. This function creates the partitions in the order it finds partition * objects in the linked list. * - * Return: TRUE Partition created - * FALSE Error, probably a range checking problem + * Return: 'true' Partition created + * 'false' Error, probably a range checking problem */ -static BOOL ldm_create_data_partitions (struct parsed_partitions *pp, +static bool ldm_create_data_partitions (struct parsed_partitions *pp, const struct ldmdb *ldb) { struct list_head *item; @@ -642,7 +637,7 @@ static BOOL ldm_create_data_partitions (struct parsed_partitions *pp, disk = ldm_get_disk_objid (ldb); if (!disk) { ldm_crit ("Can't find the ID of this disk in the database."); - return FALSE; + return false; } printk (" [LDM]"); @@ -661,7 +656,7 @@ static BOOL ldm_create_data_partitions (struct parsed_partitions *pp, } printk ("\n"); - return TRUE; + return true; } @@ -766,10 +761,10 @@ static int ldm_get_vstr (const u8 *block, u8 *buffer, int buflen) * * Read a raw VBLK Component object (version 3) into a vblk structure. * - * Return: TRUE @vb contains a Component VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Component VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, r_vstate, r_child, r_parent, r_stripe, r_cols, len; struct vblk_comp *comp; @@ -792,11 +787,11 @@ static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) len = r_parent; } if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_CMP3; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; comp = &vb->vblk.comp; ldm_get_vstr (buffer + 0x18 + r_name, comp->state, @@ -806,7 +801,7 @@ static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) comp->parent_id = ldm_get_vnum (buffer + 0x2D + r_child); comp->chunksize = r_stripe ? ldm_get_vnum (buffer+r_parent+0x2E) : 0; - return TRUE; + return true; } /** @@ -817,8 +812,8 @@ static BOOL ldm_parse_cmp3 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Disk Group object (version 3) into a vblk structure. * - * Return: TRUE @vb contains a Disk Group VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Disk Group VBLK + * 'false' @vb contents are not defined */ static int ldm_parse_dgr3 (const u8 *buffer, int buflen, struct vblk *vb) { @@ -841,16 +836,16 @@ static int ldm_parse_dgr3 (const u8 *buffer, int buflen, struct vblk *vb) len = r_diskid; } if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_DGR3; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; dgrp = &vb->vblk.dgrp; ldm_get_vstr (buffer + 0x18 + r_name, dgrp->disk_id, sizeof (dgrp->disk_id)); - return TRUE; + return true; } /** @@ -861,10 +856,10 @@ static int ldm_parse_dgr3 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Disk Group object (version 4) into a vblk structure. * - * Return: TRUE @vb contains a Disk Group VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Disk Group VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb) { char buf[64]; int r_objid, r_name, r_id1, r_id2, len; @@ -885,16 +880,16 @@ static BOOL ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb) len = r_name; } if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_DGR4; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; dgrp = &vb->vblk.dgrp; ldm_get_vstr (buffer + 0x18 + r_objid, buf, sizeof (buf)); - return TRUE; + return true; } /** @@ -905,10 +900,10 @@ static BOOL ldm_parse_dgr4 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Disk object (version 3) into a vblk structure. * - * Return: TRUE @vb contains a Disk VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Disk VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, r_diskid, r_altname, len; struct vblk_disk *disk; @@ -921,19 +916,19 @@ static BOOL ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb) r_altname = ldm_relative (buffer, buflen, 0x18, r_diskid); len = r_altname; if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_DSK3; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; disk = &vb->vblk.disk; ldm_get_vstr (buffer + 0x18 + r_diskid, disk->alt_name, sizeof (disk->alt_name)); if (!ldm_parse_guid (buffer + 0x19 + r_name, disk->disk_id)) - return FALSE; + return false; - return TRUE; + return true; } /** @@ -944,10 +939,10 @@ static BOOL ldm_parse_dsk3 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Disk object (version 4) into a vblk structure. * - * Return: TRUE @vb contains a Disk VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Disk VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, len; struct vblk_disk *disk; @@ -958,15 +953,15 @@ static BOOL ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) r_name = ldm_relative (buffer, buflen, 0x18, r_objid); len = r_name; if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_DSK4; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; disk = &vb->vblk.disk; memcpy (disk->disk_id, buffer + 0x18 + r_name, GUID_SIZE); - return TRUE; + return true; } /** @@ -977,10 +972,10 @@ static BOOL ldm_parse_dsk4 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Partition object (version 3) into a vblk structure. * - * Return: TRUE @vb contains a Partition VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Partition VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, r_size, r_parent, r_diskid, r_index, len; struct vblk_part *part; @@ -1001,11 +996,11 @@ static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) len = r_diskid; } if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_PRT3; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; part = &vb->vblk.part; part->start = BE64 (buffer + 0x24 + r_name); @@ -1018,7 +1013,7 @@ static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) else part->partnum = 0; - return TRUE; + return true; } /** @@ -1029,10 +1024,10 @@ static BOOL ldm_parse_prt3 (const u8 *buffer, int buflen, struct vblk *vb) * * Read a raw VBLK Volume object (version 5) into a vblk structure. * - * Return: TRUE @vb contains a Volume VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a Volume VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) +static bool ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) { int r_objid, r_name, r_vtype, r_child, r_size, r_id1, r_id2, r_size2; int r_drive, len; @@ -1068,11 +1063,11 @@ static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) len = r_drive; if (len < 0) - return FALSE; + return false; len += VBLK_SIZE_VOL5; if (len != BE32 (buffer + 0x14)) - return FALSE; + return false; volu = &vb->vblk.volu; @@ -1087,7 +1082,7 @@ static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) ldm_get_vstr (buffer + 0x53 + r_size, volu->drive_hint, sizeof (volu->drive_hint)); } - return TRUE; + return true; } /** @@ -1100,12 +1095,12 @@ static BOOL ldm_parse_vol5 (const u8 *buffer, int buflen, struct vblk *vb) * information common to all VBLK types, then delegates the rest of the work to * helper functions: ldm_parse_*. * - * Return: TRUE @vb contains a VBLK - * FALSE @vb contents are not defined + * Return: 'true' @vb contains a VBLK + * 'false' @vb contents are not defined */ -static BOOL ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb) +static bool ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb) { - BOOL result = FALSE; + bool result = false; int r_objid; BUG_ON (!buf || !vb); @@ -1113,7 +1108,7 @@ static BOOL ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb) r_objid = ldm_relative (buf, len, 0x18, 0); if (r_objid < 0) { ldm_error ("VBLK header is corrupt."); - return FALSE; + return false; } vb->flags = buf[0x12]; @@ -1152,10 +1147,10 @@ static BOOL ldm_parse_vblk (const u8 *buf, int len, struct vblk *vb) * * N.B. This function does not check the validity of the VBLKs. * - * Return: TRUE The VBLK was added - * FALSE An error occurred + * Return: 'true' The VBLK was added + * 'false' An error occurred */ -static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) +static bool ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) { struct vblk *vb; struct list_head *item; @@ -1165,12 +1160,12 @@ static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) vb = kmalloc (sizeof (*vb), GFP_KERNEL); if (!vb) { ldm_crit ("Out of memory."); - return FALSE; + return false; } if (!ldm_parse_vblk (data, len, vb)) { kfree(vb); - return FALSE; /* Already logged */ + return false; /* Already logged */ } /* Put vblk into the correct list. */ @@ -1196,13 +1191,13 @@ static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) if ((v->vblk.part.disk_id == vb->vblk.part.disk_id) && (v->vblk.part.start > vb->vblk.part.start)) { list_add_tail (&vb->list, &v->list); - return TRUE; + return true; } } list_add_tail (&vb->list, &ldb->v_part); break; } - return TRUE; + return true; } /** @@ -1214,10 +1209,10 @@ static BOOL ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) * Fragmented VBLKs may not be consecutive in the database, so they are placed * in a list so they can be pieced together later. * - * Return: TRUE Success, the VBLK was added to the list - * FALSE Error, a problem occurred + * Return: 'true' Success, the VBLK was added to the list + * 'false' Error, a problem occurred */ -static BOOL ldm_frag_add (const u8 *data, int size, struct list_head *frags) +static bool ldm_frag_add (const u8 *data, int size, struct list_head *frags) { struct frag *f; struct list_head *item; @@ -1230,7 +1225,7 @@ static BOOL ldm_frag_add (const u8 *data, int size, struct list_head *frags) num = BE16 (data + 0x0E); if ((num < 1) || (num > 4)) { ldm_error ("A VBLK claims to have %d parts.", num); - return FALSE; + return false; } list_for_each (item, frags) { @@ -1242,7 +1237,7 @@ static BOOL ldm_frag_add (const u8 *data, int size, struct list_head *frags) f = kmalloc (sizeof (*f) + size*num, GFP_KERNEL); if (!f) { ldm_crit ("Out of memory."); - return FALSE; + return false; } f->group = group; @@ -1255,7 +1250,7 @@ found: if (f->map & (1 << rec)) { ldm_error ("Duplicate VBLK, part %d.", rec); f->map &= 0x7F; /* Mark the group as broken */ - return FALSE; + return false; } f->map |= (1 << rec); @@ -1266,7 +1261,7 @@ found: } memcpy (f->data+rec*(size-VBLK_SIZE_HEAD)+VBLK_SIZE_HEAD, data, size); - return TRUE; + return true; } /** @@ -1295,10 +1290,10 @@ static void ldm_frag_free (struct list_head *list) * Now that all the fragmented VBLKs have been collected, they must be added to * the database for later use. * - * Return: TRUE All the fragments we added successfully - * FALSE One or more of the fragments we invalid + * Return: 'true' All the fragments we added successfully + * 'false' One or more of the fragments we invalid */ -static BOOL ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb) +static bool ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb) { struct frag *f; struct list_head *item; @@ -1311,13 +1306,13 @@ static BOOL ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb) if (f->map != 0xFF) { ldm_error ("VBLK group %d is incomplete (0x%02x).", f->group, f->map); - return FALSE; + return false; } if (!ldm_ldmdb_add (f->data, f->num*ldb->vm.vblk_size, ldb)) - return FALSE; /* Already logged */ + return false; /* Already logged */ } - return TRUE; + return true; } /** @@ -1329,16 +1324,16 @@ static BOOL ldm_frag_commit (struct list_head *frags, struct ldmdb *ldb) * To use the information from the VBLKs, they need to be read from the disk, * unpacked and validated. We cache them in @ldb according to their type. * - * Return: TRUE All the VBLKs were read successfully - * FALSE An error occurred + * Return: 'true' All the VBLKs were read successfully + * 'false' An error occurred */ -static BOOL ldm_get_vblks (struct block_device *bdev, unsigned long base, +static bool ldm_get_vblks (struct block_device *bdev, unsigned long base, struct ldmdb *ldb) { int size, perbuf, skip, finish, s, v, recs; u8 *data = NULL; Sector sect; - BOOL result = FALSE; + bool result = false; LIST_HEAD (frags); BUG_ON (!bdev || !ldb); -- cgit v1.2.3 From 52978be636374c4bfb61220b37fa12f55a071c46 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 30 Sep 2006 23:27:21 -0700 Subject: [PATCH] kmemdup: some users Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/posix_acl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 6c8dcf7613f..aec931e0997 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -58,11 +58,9 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags) if (acl) { int size = sizeof(struct posix_acl) + acl->a_count * sizeof(struct posix_acl_entry); - clone = kmalloc(size, flags); - if (clone) { - memcpy(clone, acl, size); + clone = kmemdup(acl, size, flags); + if (clone) atomic_set(&clone->a_refcount, 1); - } } return clone; } -- cgit v1.2.3 From 82b0547cfae1fb2ee26cad588f6d49a347d24740 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 30 Sep 2006 23:27:22 -0700 Subject: [PATCH] Create fs/utimes.c * fs/open.c is getting bit crowdy * preparation to lutimes(2) Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/Makefile | 2 +- fs/open.c | 134 ---------------------------------------------------------- fs/utimes.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 135 deletions(-) create mode 100644 fs/utimes.c (limited to 'fs') diff --git a/fs/Makefile b/fs/Makefile index a503e6ce0f3..819b2a93beb 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -10,7 +10,7 @@ obj-y := open.o read_write.o file_table.o super.o \ ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ seq_file.o xattr.o libfs.o fs-writeback.o \ - pnode.o drop_caches.o splice.o sync.o + pnode.o drop_caches.o splice.o sync.o utimes.o ifeq ($(CONFIG_BLOCK),y) obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o diff --git a/fs/open.c b/fs/open.c index 304c1c7814c..35c3e454458 100644 --- a/fs/open.c +++ b/fs/open.c @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -29,8 +28,6 @@ #include #include -#include - int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) { int retval = -ENODEV; @@ -353,137 +350,6 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) } #endif -#ifdef __ARCH_WANT_SYS_UTIME - -/* - * sys_utime() can be implemented in user-level using sys_utimes(). - * Is this for backwards compatibility? If so, why not move it - * into the appropriate arch directory (for those architectures that - * need it). - */ - -/* If times==NULL, set access and modification to current time, - * must be owner or have write permission. - * Else, update from *times, must be owner or super user. - */ -asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times) -{ - int error; - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; - - error = user_path_walk(filename, &nd); - if (error) - goto out; - inode = nd.dentry->d_inode; - - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; - - /* Don't worry, the checks are done in inode_change_ok() */ - newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; - if (times) { - error = -EPERM; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - goto dput_and_out; - - error = get_user(newattrs.ia_atime.tv_sec, ×->actime); - newattrs.ia_atime.tv_nsec = 0; - if (!error) - error = get_user(newattrs.ia_mtime.tv_sec, ×->modtime); - newattrs.ia_mtime.tv_nsec = 0; - if (error) - goto dput_and_out; - - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; - } else { - error = -EACCES; - if (IS_IMMUTABLE(inode)) - goto dput_and_out; - - if (current->fsuid != inode->i_uid && - (error = vfs_permission(&nd, MAY_WRITE)) != 0) - goto dput_and_out; - } - mutex_lock(&inode->i_mutex); - error = notify_change(nd.dentry, &newattrs); - mutex_unlock(&inode->i_mutex); -dput_and_out: - path_release(&nd); -out: - return error; -} - -#endif - -/* If times==NULL, set access and modification to current time, - * must be owner or have write permission. - * Else, update from *times, must be owner or super user. - */ -long do_utimes(int dfd, char __user *filename, struct timeval *times) -{ - int error; - struct nameidata nd; - struct inode * inode; - struct iattr newattrs; - - error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); - - if (error) - goto out; - inode = nd.dentry->d_inode; - - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; - - /* Don't worry, the checks are done in inode_change_ok() */ - newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; - if (times) { - error = -EPERM; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - goto dput_and_out; - - newattrs.ia_atime.tv_sec = times[0].tv_sec; - newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000; - newattrs.ia_mtime.tv_sec = times[1].tv_sec; - newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000; - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; - } else { - error = -EACCES; - if (IS_IMMUTABLE(inode)) - goto dput_and_out; - - if (current->fsuid != inode->i_uid && - (error = vfs_permission(&nd, MAY_WRITE)) != 0) - goto dput_and_out; - } - mutex_lock(&inode->i_mutex); - error = notify_change(nd.dentry, &newattrs); - mutex_unlock(&inode->i_mutex); -dput_and_out: - path_release(&nd); -out: - return error; -} - -asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes) -{ - struct timeval times[2]; - - if (utimes && copy_from_user(×, utimes, sizeof(times))) - return -EFAULT; - return do_utimes(dfd, filename, utimes ? times : NULL); -} - -asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes) -{ - return sys_futimesat(AT_FDCWD, filename, utimes); -} - - /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and diff --git a/fs/utimes.c b/fs/utimes.c new file mode 100644 index 00000000000..1bcd852fc4a --- /dev/null +++ b/fs/utimes.c @@ -0,0 +1,137 @@ +#include +#include +#include +#include +#include +#include +#include + +#ifdef __ARCH_WANT_SYS_UTIME + +/* + * sys_utime() can be implemented in user-level using sys_utimes(). + * Is this for backwards compatibility? If so, why not move it + * into the appropriate arch directory (for those architectures that + * need it). + */ + +/* If times==NULL, set access and modification to current time, + * must be owner or have write permission. + * Else, update from *times, must be owner or super user. + */ +asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times) +{ + int error; + struct nameidata nd; + struct inode * inode; + struct iattr newattrs; + + error = user_path_walk(filename, &nd); + if (error) + goto out; + inode = nd.dentry->d_inode; + + error = -EROFS; + if (IS_RDONLY(inode)) + goto dput_and_out; + + /* Don't worry, the checks are done in inode_change_ok() */ + newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; + if (times) { + error = -EPERM; + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + goto dput_and_out; + + error = get_user(newattrs.ia_atime.tv_sec, ×->actime); + newattrs.ia_atime.tv_nsec = 0; + if (!error) + error = get_user(newattrs.ia_mtime.tv_sec, ×->modtime); + newattrs.ia_mtime.tv_nsec = 0; + if (error) + goto dput_and_out; + + newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; + } else { + error = -EACCES; + if (IS_IMMUTABLE(inode)) + goto dput_and_out; + + if (current->fsuid != inode->i_uid && + (error = vfs_permission(&nd, MAY_WRITE)) != 0) + goto dput_and_out; + } + mutex_lock(&inode->i_mutex); + error = notify_change(nd.dentry, &newattrs); + mutex_unlock(&inode->i_mutex); +dput_and_out: + path_release(&nd); +out: + return error; +} + +#endif + +/* If times==NULL, set access and modification to current time, + * must be owner or have write permission. + * Else, update from *times, must be owner or super user. + */ +long do_utimes(int dfd, char __user *filename, struct timeval *times) +{ + int error; + struct nameidata nd; + struct inode * inode; + struct iattr newattrs; + + error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); + + if (error) + goto out; + inode = nd.dentry->d_inode; + + error = -EROFS; + if (IS_RDONLY(inode)) + goto dput_and_out; + + /* Don't worry, the checks are done in inode_change_ok() */ + newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; + if (times) { + error = -EPERM; + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + goto dput_and_out; + + newattrs.ia_atime.tv_sec = times[0].tv_sec; + newattrs.ia_atime.tv_nsec = times[0].tv_usec * 1000; + newattrs.ia_mtime.tv_sec = times[1].tv_sec; + newattrs.ia_mtime.tv_nsec = times[1].tv_usec * 1000; + newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; + } else { + error = -EACCES; + if (IS_IMMUTABLE(inode)) + goto dput_and_out; + + if (current->fsuid != inode->i_uid && + (error = vfs_permission(&nd, MAY_WRITE)) != 0) + goto dput_and_out; + } + mutex_lock(&inode->i_mutex); + error = notify_change(nd.dentry, &newattrs); + mutex_unlock(&inode->i_mutex); +dput_and_out: + path_release(&nd); +out: + return error; +} + +asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes) +{ + struct timeval times[2]; + + if (utimes && copy_from_user(×, utimes, sizeof(times))) + return -EFAULT; + return do_utimes(dfd, filename, utimes ? times : NULL); +} + +asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes) +{ + return sys_futimesat(AT_FDCWD, filename, utimes); +} -- cgit v1.2.3 From f5579f8c7d7e2c9eb62b566c511b21091a778157 Mon Sep 17 00:00:00 2001 From: Josef 'Jeff' Sipek Date: Sat, 30 Sep 2006 23:27:35 -0700 Subject: [PATCH] VFS: Use SEEK_{SET, CUR, END} instead of hardcoded values VFS: Use SEEK_{SET,CUR,END} instead of hardcoded values Signed-off-by: Josef 'Jeff' Sipek Acked-by: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/locks.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'fs') diff --git a/fs/locks.c b/fs/locks.c index d7c53392cac..21dfadfca2b 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -314,13 +314,13 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, off_t start, end; switch (l->l_whence) { - case 0: /*SEEK_SET*/ + case SEEK_SET: start = 0; break; - case 1: /*SEEK_CUR*/ + case SEEK_CUR: start = filp->f_pos; break; - case 2: /*SEEK_END*/ + case SEEK_END: start = i_size_read(filp->f_dentry->d_inode); break; default: @@ -364,13 +364,13 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, loff_t start; switch (l->l_whence) { - case 0: /*SEEK_SET*/ + case SEEK_SET: start = 0; break; - case 1: /*SEEK_CUR*/ + case SEEK_CUR: start = filp->f_pos; break; - case 2: /*SEEK_END*/ + case SEEK_END: start = i_size_read(filp->f_dentry->d_inode); break; default: -- cgit v1.2.3 From 54f67f631dfc25ca7a8b19200e34013abc974337 Mon Sep 17 00:00:00 2001 From: Petr Vandrovec Date: Sat, 30 Sep 2006 23:27:55 -0700 Subject: [PATCH] Move ncpfs 32bit compat ioctl to ncpfs The ncp specific compat ioctls are clearly local to one file system, so the code can better live there. This version of the patch moves everything into the generic ioctl handler and uses it for both 32 and 64 bit calls. Signed-off-by: Arnd Bergmann Signed-off-by: Petr Vandrovec Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/compat_ioctl.c | 198 -------------------------------------------- fs/ncpfs/dir.c | 3 + fs/ncpfs/file.c | 3 + fs/ncpfs/ioctl.c | 239 +++++++++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 216 insertions(+), 227 deletions(-) (limited to 'fs') diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 64b34533ede..27ca1aa3056 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -2348,193 +2347,6 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg) } } -#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) -struct ncp_ioctl_request_32 { - u32 function; - u32 size; - compat_caddr_t data; -}; - -struct ncp_fs_info_v2_32 { - s32 version; - u32 mounted_uid; - u32 connection; - u32 buffer_size; - - u32 volume_number; - u32 directory_id; - - u32 dummy1; - u32 dummy2; - u32 dummy3; -}; - -struct ncp_objectname_ioctl_32 -{ - s32 auth_type; - u32 object_name_len; - compat_caddr_t object_name; /* an userspace data, in most cases user name */ -}; - -struct ncp_privatedata_ioctl_32 -{ - u32 len; - compat_caddr_t data; /* ~1000 for NDS */ -}; - -#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct ncp_ioctl_request_32) -#define NCP_IOC_GETMOUNTUID2_32 _IOW('n', 2, u32) -#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct ncp_fs_info_v2_32) -#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct ncp_objectname_ioctl_32) -#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct ncp_privatedata_ioctl_32) -#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct ncp_privatedata_ioctl_32) - -static int do_ncp_ncprequest(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_ioctl_request_32 n32; - struct ncp_ioctl_request __user *p = compat_alloc_user_space(sizeof(*p)); - - if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32)) || - put_user(n32.function, &p->function) || - put_user(n32.size, &p->size) || - put_user(compat_ptr(n32.data), &p->data)) - return -EFAULT; - - return sys_ioctl(fd, NCP_IOC_NCPREQUEST, (unsigned long)p); -} - -static int do_ncp_getmountuid2(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - mm_segment_t old_fs = get_fs(); - __kernel_uid_t kuid; - int err; - - cmd = NCP_IOC_GETMOUNTUID2; - - set_fs(KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&kuid); - set_fs(old_fs); - - if (!err) - err = put_user(kuid, - (unsigned int __user *) compat_ptr(arg)); - - return err; -} - -static int do_ncp_getfsinfo2(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - mm_segment_t old_fs = get_fs(); - struct ncp_fs_info_v2_32 n32; - struct ncp_fs_info_v2 n; - int err; - - if (copy_from_user(&n32, compat_ptr(arg), sizeof(n32))) - return -EFAULT; - if (n32.version != NCP_GET_FS_INFO_VERSION_V2) - return -EINVAL; - n.version = NCP_GET_FS_INFO_VERSION_V2; - - set_fs(KERNEL_DS); - err = sys_ioctl(fd, NCP_IOC_GET_FS_INFO_V2, (unsigned long)&n); - set_fs(old_fs); - - if (!err) { - n32.version = n.version; - n32.mounted_uid = n.mounted_uid; - n32.connection = n.connection; - n32.buffer_size = n.buffer_size; - n32.volume_number = n.volume_number; - n32.directory_id = n.directory_id; - n32.dummy1 = n.dummy1; - n32.dummy2 = n.dummy2; - n32.dummy3 = n.dummy3; - err = copy_to_user(compat_ptr(arg), &n32, sizeof(n32)) ? -EFAULT : 0; - } - return err; -} - -static int do_ncp_getobjectname(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg); - struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p)); - s32 auth_type; - u32 name_len; - int err; - - if (copy_from_user(&n32, p32, sizeof(n32)) || - put_user(n32.object_name_len, &p->object_name_len) || - put_user(compat_ptr(n32.object_name), &p->object_name)) - return -EFAULT; - - err = sys_ioctl(fd, NCP_IOC_GETOBJECTNAME, (unsigned long)p); - if (err) - return err; - - if (get_user(auth_type, &p->auth_type) || - put_user(auth_type, &p32->auth_type) || - get_user(name_len, &p->object_name_len) || - put_user(name_len, &p32->object_name_len)) - return -EFAULT; - - return 0; -} - -static int do_ncp_setobjectname(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_objectname_ioctl_32 n32, __user *p32 = compat_ptr(arg); - struct ncp_objectname_ioctl __user *p = compat_alloc_user_space(sizeof(*p)); - - if (copy_from_user(&n32, p32, sizeof(n32)) || - put_user(n32.auth_type, &p->auth_type) || - put_user(n32.object_name_len, &p->object_name_len) || - put_user(compat_ptr(n32.object_name), &p->object_name)) - return -EFAULT; - - return sys_ioctl(fd, NCP_IOC_SETOBJECTNAME, (unsigned long)p); -} - -static int do_ncp_getprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_privatedata_ioctl_32 n32, __user *p32 = compat_ptr(arg); - struct ncp_privatedata_ioctl __user *p = - compat_alloc_user_space(sizeof(*p)); - u32 len; - int err; - - if (copy_from_user(&n32, p32, sizeof(n32)) || - put_user(n32.len, &p->len) || - put_user(compat_ptr(n32.data), &p->data)) - return -EFAULT; - - err = sys_ioctl(fd, NCP_IOC_GETPRIVATEDATA, (unsigned long)p); - if (err) - return err; - - if (get_user(len, &p->len) || - put_user(len, &p32->len)) - return -EFAULT; - - return 0; -} - -static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - struct ncp_privatedata_ioctl_32 n32; - struct ncp_privatedata_ioctl_32 __user *p32 = compat_ptr(arg); - struct ncp_privatedata_ioctl __user *p = - compat_alloc_user_space(sizeof(*p)); - - if (copy_from_user(&n32, p32, sizeof(n32)) || - put_user(n32.len, &p->len) || - put_user(compat_ptr(n32.data), &p->data)) - return -EFAULT; - - return sys_ioctl(fd, NCP_IOC_SETPRIVATEDATA, (unsigned long)p); -} -#endif - static int lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) { @@ -2748,16 +2560,6 @@ HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) HANDLE_IOCTL(RTC_EPOCH_SET32, rtc_ioctl) -#if defined(CONFIG_NCP_FS) || defined(CONFIG_NCP_FS_MODULE) -HANDLE_IOCTL(NCP_IOC_NCPREQUEST_32, do_ncp_ncprequest) -HANDLE_IOCTL(NCP_IOC_GETMOUNTUID2_32, do_ncp_getmountuid2) -HANDLE_IOCTL(NCP_IOC_GET_FS_INFO_V2_32, do_ncp_getfsinfo2) -HANDLE_IOCTL(NCP_IOC_GETOBJECTNAME_32, do_ncp_getobjectname) -HANDLE_IOCTL(NCP_IOC_SETOBJECTNAME_32, do_ncp_setobjectname) -HANDLE_IOCTL(NCP_IOC_GETPRIVATEDATA_32, do_ncp_getprivatedata) -HANDLE_IOCTL(NCP_IOC_SETPRIVATEDATA_32, do_ncp_setprivatedata) -#endif - /* dvb */ HANDLE_IOCTL(VIDEO_GET_EVENT, do_video_get_event) HANDLE_IOCTL(VIDEO_STILLPICTURE, do_video_stillpicture) diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index b4ee89250e9..458b3b78519 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -53,6 +53,9 @@ const struct file_operations ncp_dir_operations = .read = generic_read_dir, .readdir = ncp_readdir, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif }; struct inode_operations ncp_dir_inode_operations = diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c index e6b7c67cf05..df37524b85d 100644 --- a/fs/ncpfs/file.c +++ b/fs/ncpfs/file.c @@ -289,6 +289,9 @@ const struct file_operations ncp_file_operations = .read = ncp_file_read, .write = ncp_file_write, .ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif .mmap = ncp_mmap, .release = ncp_release, .fsync = ncp_fsync, diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 42039fe0653..a89ac84a824 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -7,19 +7,21 @@ * */ - -#include #include +#include #include #include #include #include #include #include +#include #include #include +#include + #include "ncplib_kernel.h" /* maximum limit for ncp_objectname_ioctl */ @@ -89,6 +91,82 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct file *file, return 0; } +#ifdef CONFIG_COMPAT +struct compat_ncp_objectname_ioctl +{ + s32 auth_type; + u32 object_name_len; + compat_caddr_t object_name; /* an userspace data, in most cases user name */ +}; + +struct compat_ncp_fs_info_v2 { + s32 version; + u32 mounted_uid; + u32 connection; + u32 buffer_size; + + u32 volume_number; + u32 directory_id; + + u32 dummy1; + u32 dummy2; + u32 dummy3; +}; + +struct compat_ncp_ioctl_request { + u32 function; + u32 size; + compat_caddr_t data; +}; + +struct compat_ncp_privatedata_ioctl +{ + u32 len; + compat_caddr_t data; /* ~1000 for NDS */ +}; + +#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct compat_ncp_fs_info_v2) +#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct compat_ncp_ioctl_request) +#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct compat_ncp_objectname_ioctl) +#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct compat_ncp_objectname_ioctl) +#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct compat_ncp_privatedata_ioctl) +#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct compat_ncp_privatedata_ioctl) + +static int +ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file, + struct compat_ncp_fs_info_v2 __user * arg) +{ + struct inode *inode = file->f_dentry->d_inode; + struct compat_ncp_fs_info_v2 info2; + + if ((file_permission(file, MAY_WRITE) != 0) + && (current->uid != server->m.mounted_uid)) { + return -EACCES; + } + if (copy_from_user(&info2, arg, sizeof(info2))) + return -EFAULT; + + if (info2.version != NCP_GET_FS_INFO_VERSION_V2) { + DPRINTK("info.version invalid: %d\n", info2.version); + return -EINVAL; + } + info2.mounted_uid = server->m.mounted_uid; + info2.connection = server->connection; + info2.buffer_size = server->buffer_size; + info2.volume_number = NCP_FINFO(inode)->volNumber; + info2.directory_id = NCP_FINFO(inode)->DosDirNum; + info2.dummy1 = info2.dummy2 = info2.dummy3 = 0; + + if (copy_to_user(arg, &info2, sizeof(info2))) + return -EFAULT; + return 0; +} +#endif + +#define NCP_IOC_GETMOUNTUID16 _IOW('n', 2, u16) +#define NCP_IOC_GETMOUNTUID32 _IOW('n', 2, u32) +#define NCP_IOC_GETMOUNTUID64 _IOW('n', 2, u64) + #ifdef CONFIG_NCPFS_NLS /* Here we are select the iocharset and the codepage for NLS. * Thanks Petr Vandrovec for idea and many hints. @@ -192,12 +270,24 @@ int ncp_ioctl(struct inode *inode, struct file *filp, void __user *argp = (void __user *)arg; switch (cmd) { +#ifdef CONFIG_COMPAT + case NCP_IOC_NCPREQUEST_32: +#endif case NCP_IOC_NCPREQUEST: - if ((file_permission(filp, MAY_WRITE) != 0) && (current->uid != server->m.mounted_uid)) { return -EACCES; } +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_NCPREQUEST_32) { + struct compat_ncp_ioctl_request request32; + if (copy_from_user(&request32, argp, sizeof(request32))) + return -EFAULT; + request.function = request32.function; + request.size = request32.size; + request.data = compat_ptr(request32.data); + } else +#endif if (copy_from_user(&request, argp, sizeof(request))) return -EFAULT; @@ -254,19 +344,35 @@ int ncp_ioctl(struct inode *inode, struct file *filp, case NCP_IOC_GET_FS_INFO_V2: return ncp_get_fs_info_v2(server, filp, argp); - case NCP_IOC_GETMOUNTUID2: - { - unsigned long tmp = server->m.mounted_uid; - - if ((file_permission(filp, MAY_READ) != 0) - && (current->uid != server->m.mounted_uid)) - { - return -EACCES; - } - if (put_user(tmp, (unsigned long __user *)argp)) +#ifdef CONFIG_COMPAT + case NCP_IOC_GET_FS_INFO_V2_32: + return ncp_get_compat_fs_info_v2(server, filp, argp); +#endif + /* we have too many combinations of CONFIG_COMPAT, + * CONFIG_64BIT and CONFIG_UID16, so just handle + * any of the possible ioctls */ + case NCP_IOC_GETMOUNTUID16: + case NCP_IOC_GETMOUNTUID32: + case NCP_IOC_GETMOUNTUID64: + if ((file_permission(filp, MAY_READ) != 0) + && (current->uid != server->m.mounted_uid)) { + return -EACCES; + } + if (cmd == NCP_IOC_GETMOUNTUID16) { + u16 uid; + SET_UID(uid, server->m.mounted_uid); + if (put_user(uid, (u16 __user *)argp)) + return -EFAULT; + } else if (cmd == NCP_IOC_GETMOUNTUID32) { + if (put_user(server->m.mounted_uid, + (u32 __user *)argp)) + return -EFAULT; + } else { + if (put_user(server->m.mounted_uid, + (u64 __user *)argp)) return -EFAULT; - return 0; } + return 0; case NCP_IOC_GETROOT: { @@ -476,6 +582,32 @@ outrel: } #endif /* CONFIG_NCPFS_IOCTL_LOCKING */ +#ifdef CONFIG_COMPAT + case NCP_IOC_GETOBJECTNAME_32: + if (current->uid != server->m.mounted_uid) { + return -EACCES; + } + { + struct compat_ncp_objectname_ioctl user; + size_t outl; + + if (copy_from_user(&user, argp, sizeof(user))) + return -EFAULT; + user.auth_type = server->auth.auth_type; + outl = user.object_name_len; + user.object_name_len = server->auth.object_name_len; + if (outl > user.object_name_len) + outl = user.object_name_len; + if (outl) { + if (copy_to_user(compat_ptr(user.object_name), + server->auth.object_name, + outl)) return -EFAULT; + } + if (copy_to_user(argp, &user, sizeof(user))) + return -EFAULT; + return 0; + } +#endif case NCP_IOC_GETOBJECTNAME: if (current->uid != server->m.mounted_uid) { return -EACCES; @@ -500,6 +632,9 @@ outrel: return -EFAULT; return 0; } +#ifdef CONFIG_COMPAT + case NCP_IOC_SETOBJECTNAME_32: +#endif case NCP_IOC_SETOBJECTNAME: if (current->uid != server->m.mounted_uid) { return -EACCES; @@ -512,8 +647,19 @@ outrel: void* oldprivate; size_t oldprivatelen; +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_SETOBJECTNAME_32) { + struct compat_ncp_objectname_ioctl user32; + if (copy_from_user(&user32, argp, sizeof(user32))) + return -EFAULT; + user.auth_type = user32.auth_type; + user.object_name_len = user32.object_name_len; + user.object_name = compat_ptr(user32.object_name); + } else +#endif if (copy_from_user(&user, argp, sizeof(user))) return -EFAULT; + if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN) return -ENOMEM; if (user.object_name_len) { @@ -544,6 +690,9 @@ outrel: kfree(oldname); return 0; } +#ifdef CONFIG_COMPAT + case NCP_IOC_GETPRIVATEDATA_32: +#endif case NCP_IOC_GETPRIVATEDATA: if (current->uid != server->m.mounted_uid) { return -EACCES; @@ -552,8 +701,18 @@ outrel: struct ncp_privatedata_ioctl user; size_t outl; +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_GETPRIVATEDATA_32) { + struct compat_ncp_privatedata_ioctl user32; + if (copy_from_user(&user32, argp, sizeof(user32))) + return -EFAULT; + user.len = user32.len; + user.data = compat_ptr(user32.data); + } else +#endif if (copy_from_user(&user, argp, sizeof(user))) return -EFAULT; + outl = user.len; user.len = server->priv.len; if (outl > user.len) outl = user.len; @@ -562,10 +721,23 @@ outrel: server->priv.data, outl)) return -EFAULT; } +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_GETPRIVATEDATA_32) { + struct compat_ncp_privatedata_ioctl user32; + user32.len = user.len; + user32.data = (unsigned long) user.data; + if (copy_to_user(&user32, argp, sizeof(user32))) + return -EFAULT; + } else +#endif if (copy_to_user(argp, &user, sizeof(user))) return -EFAULT; + return 0; } +#ifdef CONFIG_COMPAT + case NCP_IOC_SETPRIVATEDATA_32: +#endif case NCP_IOC_SETPRIVATEDATA: if (current->uid != server->m.mounted_uid) { return -EACCES; @@ -576,8 +748,18 @@ outrel: void* old; size_t oldlen; +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_SETPRIVATEDATA_32) { + struct compat_ncp_privatedata_ioctl user32; + if (copy_from_user(&user32, argp, sizeof(user32))) + return -EFAULT; + user.len = user32.len; + user.data = compat_ptr(user32.data); + } else +#endif if (copy_from_user(&user, argp, sizeof(user))) return -EFAULT; + if (user.len > NCP_PRIVATE_DATA_MAX_LEN) return -ENOMEM; if (user.len) { @@ -636,20 +818,19 @@ outrel: } } -/* #ifdef CONFIG_UID16 */ - /* NCP_IOC_GETMOUNTUID may be same as NCP_IOC_GETMOUNTUID2, - so we have this out of switch */ - if (cmd == NCP_IOC_GETMOUNTUID) { - __kernel_uid_t uid = 0; - if ((file_permission(filp, MAY_READ) != 0) - && (current->uid != server->m.mounted_uid)) { - return -EACCES; - } - SET_UID(uid, server->m.mounted_uid); - if (put_user(uid, (__kernel_uid_t __user *)argp)) - return -EFAULT; - return 0; - } -/* #endif */ return -EINVAL; } + +#ifdef CONFIG_COMPAT +long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file->f_dentry->d_inode; + int ret; + + lock_kernel(); + arg = (unsigned long) compat_ptr(arg); + ret = ncp_ioctl(inode, file, cmd, arg); + unlock_kernel(); + return ret; +} +#endif -- cgit v1.2.3 From e1fabd3ccf02901374bffa434e0af472749a5bd9 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Sat, 30 Sep 2006 23:28:40 -0700 Subject: [PATCH] reiserfs: fix is_reusable bitmap check to not traverse the bitmap info array There is a check in is_reusable to determine if a particular block is a bitmap block. It verifies this by going through the array of bitmap block buffer heads and comparing the block number to each one. Bitmap blocks are at defined locations on the disk in both old and current formats. Simply checking against the known good values is enough. This is a trivial optimization for a non-production codepath, but this is the first in a series of patches that will ultimately remove the buffer heads from that array. Signed-off-by: Jeff Mahoney Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/bitmap.c | 40 +++++++++++++++++++++++++--------------- fs/reiserfs/super.c | 2 ++ 2 files changed, 27 insertions(+), 15 deletions(-) (limited to 'fs') diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 4a7dbdee1b6..1022347a211 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -50,16 +50,15 @@ static inline void get_bit_address(struct super_block *s, { /* It is in the bitmap block number equal to the block * number divided by the number of bits in a block. */ - *bmap_nr = block / (s->s_blocksize << 3); + *bmap_nr = block >> (s->s_blocksize_bits + 3); /* Within that bitmap block it is located at bit offset *offset. */ *offset = block & ((s->s_blocksize << 3) - 1); - return; } #ifdef CONFIG_REISERFS_CHECK int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) { - int i, j; + int bmap, offset; if (block == 0 || block >= SB_BLOCK_COUNT(s)) { reiserfs_warning(s, @@ -68,34 +67,45 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) return 0; } - /* it can't be one of the bitmap blocks */ - for (i = 0; i < SB_BMAP_NR(s); i++) - if (block == SB_AP_BITMAP(s)[i].bh->b_blocknr) { + get_bit_address(s, block, &bmap, &offset); + + /* Old format filesystem? Unlikely, but the bitmaps are all up front so + * we need to account for it. */ + if (unlikely(test_bit(REISERFS_OLD_FORMAT, + &(REISERFS_SB(s)->s_properties)))) { + b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; + if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) { + reiserfs_warning(s, "vs: 4019: is_reusable: " + "bitmap block %lu(%u) can't be freed or reused", + block, SB_BMAP_NR(s)); + return 0; + } + } else { + if (offset == 0) { reiserfs_warning(s, "vs: 4020: is_reusable: " "bitmap block %lu(%u) can't be freed or reused", block, SB_BMAP_NR(s)); return 0; } + } - get_bit_address(s, block, &i, &j); - - if (i >= SB_BMAP_NR(s)) { + if (bmap >= SB_BMAP_NR(s)) { reiserfs_warning(s, "vs-4030: is_reusable: there is no so many bitmap blocks: " - "block=%lu, bitmap_nr=%d", block, i); + "block=%lu, bitmap_nr=%d", block, bmap); return 0; } if ((bit_value == 0 && - reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) || + reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data)) || (bit_value == 1 && - reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data) == 0)) { + reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data) == 0)) { reiserfs_warning(s, "vs-4040: is_reusable: corresponding bit of block %lu does not " - "match required value (i==%d, j==%d) test_bit==%d", - block, i, j, reiserfs_test_le_bit(j, + "match required value (bmap==%d, offset==%d) test_bit==%d", + block, bmap, offset, reiserfs_test_le_bit(offset, SB_AP_BITMAP - (s)[i].bh-> + (s)[bmap].bh-> b_data)); return 0; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 80fc3b32802..db2c581df76 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1818,6 +1818,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) if (is_reiserfs_3_5(rs) || (is_reiserfs_jr(rs) && SB_VERSION(s) == REISERFS_VERSION_1)) set_bit(REISERFS_3_5, &(sbi->s_properties)); + else if (old_format) + set_bit(REISERFS_OLD_FORMAT, &(sbi->s_properties)); else set_bit(REISERFS_3_6, &(sbi->s_properties)); -- cgit v1.2.3 From 0b3dc17bc0c0997bde9f5d7691ec0cae24258cf7 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Sat, 30 Sep 2006 23:28:42 -0700 Subject: [PATCH] reiserfs: clean up bitmap block buffer head references Similar to the SB_JOURNAL cleanup that was accepted a while ago, this patch uses a temporary variable for buffer head references from the bitmap info array. This makes the code much more readable in some areas. It also uses proper reference counting, doing a get_bh() after using the pointer from the array and brelse()'ing it later. This may seem silly, but a later patch will replace the simple temporary variables with an actual read, so the reference freeing will be used then. Signed-off-by: Jeff Mahoney Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/bitmap.c | 60 +++++++++++++++++++++++++++++++--------------------- fs/reiserfs/resize.c | 60 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 71 insertions(+), 49 deletions(-) (limited to 'fs') diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 1022347a211..44d9410e9d6 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -59,6 +59,7 @@ static inline void get_bit_address(struct super_block *s, int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) { int bmap, offset; + struct buffer_head *bh; if (block == 0 || block >= SB_BLOCK_COUNT(s)) { reiserfs_warning(s, @@ -96,20 +97,21 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) return 0; } - if ((bit_value == 0 && - reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data)) || - (bit_value == 1 && - reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data) == 0)) { + bh = SB_AP_BITMAP(s)[bmap].bh; + get_bh(bh); + + if ((bit_value == 0 && reiserfs_test_le_bit(offset, bh->b_data)) || + (bit_value == 1 && reiserfs_test_le_bit(offset, bh->b_data) == 0)) { reiserfs_warning(s, "vs-4040: is_reusable: corresponding bit of block %lu does not " "match required value (bmap==%d, offset==%d) test_bit==%d", - block, bmap, offset, reiserfs_test_le_bit(offset, - SB_AP_BITMAP - (s)[bmap].bh-> - b_data)); + block, bmap, offset, + reiserfs_test_le_bit(offset, bh->b_data)); + brelse(bh); return 0; } + brelse(bh); if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { reiserfs_warning(s, @@ -151,6 +153,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, { struct super_block *s = th->t_super; struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n]; + struct buffer_head *bh; int end, next; int org = *beg; @@ -169,22 +172,28 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, bmap_n); return 0; } - if (buffer_locked(bi->bh)) { + bh = bi->bh; + get_bh(bh); + + if (buffer_locked(bh)) { PROC_INFO_INC(s, scan_bitmap.wait); - __wait_on_buffer(bi->bh); + __wait_on_buffer(bh); } while (1) { cont: - if (bi->free_count < min) + if (bi->free_count < min) { + brelse(bh); return 0; // No free blocks in this bitmap + } /* search for a first zero bit -- beggining of a window */ *beg = reiserfs_find_next_zero_le_bit - ((unsigned long *)(bi->bh->b_data), boundary, *beg); + ((unsigned long *)(bh->b_data), boundary, *beg); if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block * cannot contain a zero window of minimum size */ + brelse(bh); return 0; } @@ -193,7 +202,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, /* first zero bit found; we check next bits */ for (end = *beg + 1;; end++) { if (end >= *beg + max || end >= boundary - || reiserfs_test_le_bit(end, bi->bh->b_data)) { + || reiserfs_test_le_bit(end, bh->b_data)) { next = end; break; } @@ -207,12 +216,12 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, * (end) points to one bit after the window end */ if (end - *beg >= min) { /* it seems we have found window of proper size */ int i; - reiserfs_prepare_for_journal(s, bi->bh, 1); + reiserfs_prepare_for_journal(s, bh, 1); /* try to set all blocks used checking are they still free */ for (i = *beg; i < end; i++) { /* It seems that we should not check in journal again. */ if (reiserfs_test_and_set_le_bit - (i, bi->bh->b_data)) { + (i, bh->b_data)) { /* bit was set by another process * while we slept in prepare_for_journal() */ PROC_INFO_INC(s, scan_bitmap.stolen); @@ -224,17 +233,16 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, /* otherwise we clear all bit were set ... */ while (--i >= *beg) reiserfs_test_and_clear_le_bit - (i, bi->bh->b_data); - reiserfs_restore_prepared_buffer(s, - bi-> - bh); + (i, bh->b_data); + reiserfs_restore_prepared_buffer(s, bh); *beg = org; /* ... and search again in current block from beginning */ goto cont; } } bi->free_count -= (end - *beg); - journal_mark_dirty(th, s, bi->bh); + journal_mark_dirty(th, s, bh); + brelse(bh); /* free block count calculation */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), @@ -383,7 +391,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, { struct super_block *s = th->t_super; struct reiserfs_super_block *rs; - struct buffer_head *sbh; + struct buffer_head *sbh, *bmbh; struct reiserfs_bitmap_info *apbi; int nr, offset; @@ -404,16 +412,20 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, return; } - reiserfs_prepare_for_journal(s, apbi[nr].bh, 1); + bmbh = apbi[nr].bh; + get_bh(bmbh); + + reiserfs_prepare_for_journal(s, bmbh, 1); /* clear bit for the given block in bit map */ - if (!reiserfs_test_and_clear_le_bit(offset, apbi[nr].bh->b_data)) { + if (!reiserfs_test_and_clear_le_bit(offset, bmbh->b_data)) { reiserfs_warning(s, "vs-4080: reiserfs_free_block: " "free_block (%s:%lu)[dev:blocknr]: bit already cleared", reiserfs_bdevname(s), block); } apbi[nr].free_count++; - journal_mark_dirty(th, s, apbi[nr].bh); + journal_mark_dirty(th, s, bmbh); + brelse(bmbh); reiserfs_prepare_for_journal(s, sbh, 1); /* update super block */ diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 39cc7f47f5d..958b7597899 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c @@ -22,6 +22,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) int err = 0; struct reiserfs_super_block *sb; struct reiserfs_bitmap_info *bitmap; + struct reiserfs_bitmap_info *info; struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s); struct buffer_head *bh; struct reiserfs_transaction_handle th; @@ -127,16 +128,19 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) * transaction begins, and the new bitmaps don't matter if the * transaction fails. */ for (i = bmap_nr; i < bmap_nr_new; i++) { - bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8); - memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb)); - reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data); - - set_buffer_uptodate(bitmap[i].bh); - mark_buffer_dirty(bitmap[i].bh); - sync_dirty_buffer(bitmap[i].bh); + bh = sb_getblk(s, i * s->s_blocksize * 8); + get_bh(bh); + memset(bh->b_data, 0, sb_blocksize(sb)); + reiserfs_test_and_set_le_bit(0, bh->b_data); + + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + sync_dirty_buffer(bh); // update bitmap_info stuff bitmap[i].first_zero_hint = 1; bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; + bitmap[i].bh = bh; + brelse(bh); } /* free old bitmap blocks array */ SB_AP_BITMAP(s) = bitmap; @@ -150,30 +154,36 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) if (err) return err; - /* correct last bitmap blocks in old and new disk layout */ - reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1); + /* Extend old last bitmap block - new blocks have been made available */ + info = SB_AP_BITMAP(s) + bmap_nr - 1; + bh = info->bh; + get_bh(bh); + + reiserfs_prepare_for_journal(s, bh, 1); for (i = block_r; i < s->s_blocksize * 8; i++) - reiserfs_test_and_clear_le_bit(i, - SB_AP_BITMAP(s)[bmap_nr - - 1].bh->b_data); - SB_AP_BITMAP(s)[bmap_nr - 1].free_count += s->s_blocksize * 8 - block_r; - if (!SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint) - SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r; + reiserfs_test_and_clear_le_bit(i, bh->b_data); + info->free_count += s->s_blocksize * 8 - block_r; + if (!info->first_zero_hint) + info->first_zero_hint = block_r; + + journal_mark_dirty(&th, s, bh); + brelse(bh); - journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh); + /* Correct new last bitmap block - It may not be full */ + info = SB_AP_BITMAP(s) + bmap_nr_new - 1; + bh = info->bh; + get_bh(bh); - reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1); + reiserfs_prepare_for_journal(s, bh, 1); for (i = block_r_new; i < s->s_blocksize * 8; i++) - reiserfs_test_and_set_le_bit(i, - SB_AP_BITMAP(s)[bmap_nr_new - - 1].bh->b_data); - journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh); + reiserfs_test_and_set_le_bit(i, bh->b_data); + journal_mark_dirty(&th, s, bh); + brelse(bh); - SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -= - s->s_blocksize * 8 - block_r_new; + info->free_count -= s->s_blocksize * 8 - block_r_new; /* Extreme case where last bitmap is the only valid block in itself. */ - if (!SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count) - SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0; + if (!info->free_count) + info->first_zero_hint = 0; /* update super */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); free_blocks = SB_FREE_BLOCKS(s); -- cgit v1.2.3 From 6f01046b35d940079822827498a7dd6d3eec8c6b Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Sat, 30 Sep 2006 23:28:43 -0700 Subject: [PATCH] reiserfs: reorganize bitmap loading functions This patch moves the bitmap loading code from super.c to bitmap.c The code is also restructured somewhat. The only difference between new format bitmaps and old format bitmaps is where they are. That's a two liner before loading the block to use the correct one. There's no need for an entirely separate code path. The load path is generally the same, with the pattern being to throw out a bunch of requests and then wait for them, then cache the metadata from the contents. Again, like the previous patches, the purpose is to set up for later ones. Update: There was a bug in the previously posted version of this that resulted in corruption. The problem was that bitmap 0 on new format file systems must be treated specially, and wasn't. A stupid bug with an easy fix. This is hopefully the last fix for the disaster that is the reiserfs bitmap patch set. If a bitmap block was full, first_zero_hint would end up at zero since it would never be changed from it's zeroed out value. This just sets it beyond the end of the bitmap block. If any bits are freed, it will be reset to a valid bit. When info->free_count = 0, then we already know it's full. Signed-off-by: Jeff Mahoney Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/bitmap.c | 88 +++++++++++++++++++++++++++++++++++++++ fs/reiserfs/resize.c | 1 + fs/reiserfs/super.c | 114 +-------------------------------------------------- 3 files changed, 90 insertions(+), 113 deletions(-) (limited to 'fs') diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 44d9410e9d6..abdd6d9c455 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -1285,3 +1286,90 @@ int reiserfs_can_fit_pages(struct super_block *sb /* superblock of filesystem return space > 0 ? space : 0; } + +void reiserfs_cache_bitmap_metadata(struct super_block *sb, + struct buffer_head *bh, + struct reiserfs_bitmap_info *info) +{ + unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size); + + info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3); + + while (--cur >= (unsigned long *)bh->b_data) { + int base = ((char *)cur - bh->b_data) << 3; + + /* 0 and ~0 are special, we can optimize for them */ + if (*cur == 0) { + info->first_zero_hint = base; + info->free_count += BITS_PER_LONG; + } else if (*cur != ~0L) { /* A mix, investigate */ + int b; + for (b = BITS_PER_LONG - 1; b >= 0; b--) { + if (!reiserfs_test_le_bit(b, cur)) { + info->first_zero_hint = base + b; + info->free_count++; + } + } + } + } + /* The first bit must ALWAYS be 1 */ + BUG_ON(info->first_zero_hint == 0); +} + +struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, + unsigned int bitmap) +{ + b_blocknr_t block = (sb->s_blocksize << 3) * bitmap; + struct buffer_head *bh; + + /* Way old format filesystems had the bitmaps packed up front. + * I doubt there are any of these left, but just in case... */ + if (unlikely(test_bit(REISERFS_OLD_FORMAT, + &(REISERFS_SB(sb)->s_properties)))) + block = REISERFS_SB(sb)->s_sbh->b_blocknr + 1 + bitmap; + else if (bitmap == 0) + block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; + + bh = sb_getblk(sb, block); + if (!buffer_uptodate(bh)) + ll_rw_block(READ, 1, &bh); + + return bh; +} + +int reiserfs_init_bitmap_cache(struct super_block *sb) +{ + struct reiserfs_bitmap_info *bitmap; + int i; + + bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); + if (bitmap == NULL) + return -ENOMEM; + + memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); + + for (i = 0; i < SB_BMAP_NR(sb); i++) + bitmap[i].bh = reiserfs_read_bitmap_block(sb, i); + + /* make sure we have them all */ + for (i = 0; i < SB_BMAP_NR(sb); i++) { + wait_on_buffer(bitmap[i].bh); + if (!buffer_uptodate(bitmap[i].bh)) { + reiserfs_warning(sb, "sh-2029: %s: " + "bitmap block (#%lu) reading failed", + __FUNCTION__, bitmap[i].bh->b_blocknr); + for (i = 0; i < SB_BMAP_NR(sb); i++) + brelse(bitmap[i].bh); + vfree(bitmap); + return -EIO; + } + } + + /* Cache the info on the bitmaps before we get rolling */ + for (i = 0; i < SB_BMAP_NR(sb); i++) + reiserfs_cache_bitmap_metadata(sb, bitmap[i].bh, &bitmap[i]); + + SB_AP_BITMAP(sb) = bitmap; + + return 0; +} diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 958b7597899..90d39fd3096 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c @@ -132,6 +132,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) get_bh(bh); memset(bh->b_data, 0, sb_blocksize(sb)); reiserfs_test_and_set_le_bit(0, bh->b_data); + reiserfs_cache_bitmap_metadata(s, bh, bitmap + i); set_buffer_uptodate(bh); mark_buffer_dirty(bh); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index db2c581df76..c78e99e196f 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1243,118 +1243,6 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) return 0; } -/* load_bitmap_info_data - Sets up the reiserfs_bitmap_info structure from disk. - * @sb - superblock for this filesystem - * @bi - the bitmap info to be loaded. Requires that bi->bh is valid. - * - * This routine counts how many free bits there are, finding the first zero - * as a side effect. Could also be implemented as a loop of test_bit() calls, or - * a loop of find_first_zero_bit() calls. This implementation is similar to - * find_first_zero_bit(), but doesn't return after it finds the first bit. - * Should only be called on fs mount, but should be fairly efficient anyways. - * - * bi->first_zero_hint is considered unset if it == 0, since the bitmap itself - * will * invariably occupt block 0 represented in the bitmap. The only - * exception to this is when free_count also == 0, since there will be no - * free blocks at all. - */ - -static void load_bitmap_info_data(struct super_block *sb, - struct reiserfs_bitmap_info *bi) -{ - unsigned long *cur = (unsigned long *)bi->bh->b_data; - - while ((char *)cur < (bi->bh->b_data + sb->s_blocksize)) { - - /* No need to scan if all 0's or all 1's. - * Since we're only counting 0's, we can simply ignore all 1's */ - if (*cur == 0) { - if (bi->first_zero_hint == 0) { - bi->first_zero_hint = - ((char *)cur - bi->bh->b_data) << 3; - } - bi->free_count += sizeof(unsigned long) * 8; - } else if (*cur != ~0L) { - int b; - for (b = 0; b < sizeof(unsigned long) * 8; b++) { - if (!reiserfs_test_le_bit(b, cur)) { - bi->free_count++; - if (bi->first_zero_hint == 0) - bi->first_zero_hint = - (((char *)cur - - bi->bh->b_data) << 3) + b; - } - } - } - cur++; - } - -#ifdef CONFIG_REISERFS_CHECK -// This outputs a lot of unneded info on big FSes -// reiserfs_warning ("bitmap loaded from block %d: %d free blocks", -// bi->bh->b_blocknr, bi->free_count); -#endif -} - -static int read_bitmaps(struct super_block *s) -{ - int i, bmap_nr; - - SB_AP_BITMAP(s) = - vmalloc(sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s)); - if (SB_AP_BITMAP(s) == 0) - return 1; - memset(SB_AP_BITMAP(s), 0, - sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s)); - for (i = 0, bmap_nr = - REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1; - i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) { - SB_AP_BITMAP(s)[i].bh = sb_getblk(s, bmap_nr); - if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) - ll_rw_block(READ, 1, &SB_AP_BITMAP(s)[i].bh); - } - for (i = 0; i < SB_BMAP_NR(s); i++) { - wait_on_buffer(SB_AP_BITMAP(s)[i].bh); - if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) { - reiserfs_warning(s, "sh-2029: reiserfs read_bitmaps: " - "bitmap block (#%lu) reading failed", - SB_AP_BITMAP(s)[i].bh->b_blocknr); - for (i = 0; i < SB_BMAP_NR(s); i++) - brelse(SB_AP_BITMAP(s)[i].bh); - vfree(SB_AP_BITMAP(s)); - SB_AP_BITMAP(s) = NULL; - return 1; - } - load_bitmap_info_data(s, SB_AP_BITMAP(s) + i); - } - return 0; -} - -static int read_old_bitmaps(struct super_block *s) -{ - int i; - struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s); - int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */ - - /* read true bitmap */ - SB_AP_BITMAP(s) = - vmalloc(sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs)); - if (SB_AP_BITMAP(s) == 0) - return 1; - - memset(SB_AP_BITMAP(s), 0, - sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs)); - - for (i = 0; i < sb_bmap_nr(rs); i++) { - SB_AP_BITMAP(s)[i].bh = sb_bread(s, bmp1 + i); - if (!SB_AP_BITMAP(s)[i].bh) - return 1; - load_bitmap_info_data(s, SB_AP_BITMAP(s) + i); - } - - return 0; -} - static int read_super_block(struct super_block *s, int offset) { struct buffer_head *bh; @@ -1736,7 +1624,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) sbi->s_mount_state = SB_REISERFS_STATE(s); sbi->s_mount_state = REISERFS_VALID_FS; - if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { + if ((errval = reiserfs_init_bitmap_cache(s))) { SWARN(silent, s, "jmacd-8: reiserfs_fill_super: unable to read bitmap"); goto error; -- cgit v1.2.3 From 5065227b46235ec0131b383cc2f537069b55c6b6 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Sat, 30 Sep 2006 23:28:44 -0700 Subject: [PATCH] reiserfs: on-demand bitmap loading This is the patch the three previous ones have been leading up to. It changes the behavior of ReiserFS from loading and caching all the bitmaps as special, to treating the bitmaps like any other bit of metadata and just letting the system-wide caches figure out what to hang on to. Buffer heads are allocated on the fly, so there is no need to retain pointers to all of them. The caching of the metadata occurs when the data is read and updated, and is considered invalid and uncached until then. I needed to remove the vs-4040 check for performing a duplicate operation on a particular bit. The reason is that while the other sites for working with bitmaps are allowed to schedule, is_reusable() is called from do_balance(), which will panic if a schedule occurs in certain places. The benefit of on-demand bitmaps clearly outweighs a sanity check that depends on a compile-time option that is discouraged. [akpm@osdl.org: warning fix] Signed-off-by: Jeff Mahoney Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/bitmap.c | 97 ++++++++++++++++++++++++---------------------------- fs/reiserfs/resize.c | 24 +++++++++---- fs/reiserfs/super.c | 39 +++++---------------- 3 files changed, 70 insertions(+), 90 deletions(-) (limited to 'fs') diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index abdd6d9c455..cca1dbf5458 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -60,7 +60,6 @@ static inline void get_bit_address(struct super_block *s, int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) { int bmap, offset; - struct buffer_head *bh; if (block == 0 || block >= SB_BLOCK_COUNT(s)) { reiserfs_warning(s, @@ -98,22 +97,6 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) return 0; } - bh = SB_AP_BITMAP(s)[bmap].bh; - get_bh(bh); - - if ((bit_value == 0 && reiserfs_test_le_bit(offset, bh->b_data)) || - (bit_value == 1 && reiserfs_test_le_bit(offset, bh->b_data) == 0)) { - reiserfs_warning(s, - "vs-4040: is_reusable: corresponding bit of block %lu does not " - "match required value (bmap==%d, offset==%d) test_bit==%d", - block, bmap, offset, - reiserfs_test_le_bit(offset, bh->b_data)); - - brelse(bh); - return 0; - } - brelse(bh); - if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { reiserfs_warning(s, "vs-4050: is_reusable: this is root block (%u), " @@ -173,13 +156,10 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, bmap_n); return 0; } - bh = bi->bh; - get_bh(bh); - if (buffer_locked(bh)) { - PROC_INFO_INC(s, scan_bitmap.wait); - __wait_on_buffer(bh); - } + bh = reiserfs_read_bitmap_block(s, bmap_n); + if (bh == NULL) + return 0; while (1) { cont: @@ -285,9 +265,20 @@ static int bmap_hash_id(struct super_block *s, u32 id) */ static inline int block_group_used(struct super_block *s, u32 id) { - int bm; - bm = bmap_hash_id(s, id); - if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100)) { + int bm = bmap_hash_id(s, id); + struct reiserfs_bitmap_info *info = &SB_AP_BITMAP(s)[bm]; + + /* If we don't have cached information on this bitmap block, we're + * going to have to load it later anyway. Loading it here allows us + * to make a better decision. This favors long-term performace gain + * with a better on-disk layout vs. a short term gain of skipping the + * read and potentially having a bad placement. */ + if (info->first_zero_hint == 0) { + struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); + brelse(bh); + } + + if (info->free_count > ((s->s_blocksize << 3) * 60 / 100)) { return 0; } return 1; @@ -413,8 +404,9 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, return; } - bmbh = apbi[nr].bh; - get_bh(bmbh); + bmbh = reiserfs_read_bitmap_block(s, nr); + if (!bmbh) + return; reiserfs_prepare_for_journal(s, bmbh, 1); @@ -1320,6 +1312,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, unsigned int bitmap) { b_blocknr_t block = (sb->s_blocksize << 3) * bitmap; + struct reiserfs_bitmap_info *info = SB_AP_BITMAP(sb) + bitmap; struct buffer_head *bh; /* Way old format filesystems had the bitmaps packed up front. @@ -1330,9 +1323,21 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, else if (bitmap == 0) block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; - bh = sb_getblk(sb, block); - if (!buffer_uptodate(bh)) - ll_rw_block(READ, 1, &bh); + bh = sb_bread(sb, block); + if (bh == NULL) + reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%lu) " + "reading failed", __FUNCTION__, bh->b_blocknr); + else { + if (buffer_locked(bh)) { + PROC_INFO_INC(sb, scan_bitmap.wait); + __wait_on_buffer(bh); + } + BUG_ON(!buffer_uptodate(bh)); + BUG_ON(atomic_read(&bh->b_count) == 0); + + if (info->first_zero_hint == 0) + reiserfs_cache_bitmap_metadata(sb, bh, info); + } return bh; } @@ -1340,7 +1345,6 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, int reiserfs_init_bitmap_cache(struct super_block *sb) { struct reiserfs_bitmap_info *bitmap; - int i; bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); if (bitmap == NULL) @@ -1348,28 +1352,15 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); - for (i = 0; i < SB_BMAP_NR(sb); i++) - bitmap[i].bh = reiserfs_read_bitmap_block(sb, i); - - /* make sure we have them all */ - for (i = 0; i < SB_BMAP_NR(sb); i++) { - wait_on_buffer(bitmap[i].bh); - if (!buffer_uptodate(bitmap[i].bh)) { - reiserfs_warning(sb, "sh-2029: %s: " - "bitmap block (#%lu) reading failed", - __FUNCTION__, bitmap[i].bh->b_blocknr); - for (i = 0; i < SB_BMAP_NR(sb); i++) - brelse(bitmap[i].bh); - vfree(bitmap); - return -EIO; - } - } - - /* Cache the info on the bitmaps before we get rolling */ - for (i = 0; i < SB_BMAP_NR(sb); i++) - reiserfs_cache_bitmap_metadata(sb, bitmap[i].bh, &bitmap[i]); - SB_AP_BITMAP(sb) = bitmap; return 0; } + +void reiserfs_free_bitmap_cache(struct super_block *sb) +{ + if (SB_AP_BITMAP(sb)) { + vfree(SB_AP_BITMAP(sb)); + SB_AP_BITMAP(sb) = NULL; + } +} diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 90d39fd3096..315684793d1 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c @@ -128,8 +128,9 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) * transaction begins, and the new bitmaps don't matter if the * transaction fails. */ for (i = bmap_nr; i < bmap_nr_new; i++) { - bh = sb_getblk(s, i * s->s_blocksize * 8); - get_bh(bh); + /* don't use read_bitmap_block since it will cache + * the uninitialized bitmap */ + bh = sb_bread(s, i * s->s_blocksize * 8); memset(bh->b_data, 0, sb_blocksize(sb)); reiserfs_test_and_set_le_bit(0, bh->b_data); reiserfs_cache_bitmap_metadata(s, bh, bitmap + i); @@ -140,7 +141,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) // update bitmap_info stuff bitmap[i].first_zero_hint = 1; bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; - bitmap[i].bh = bh; brelse(bh); } /* free old bitmap blocks array */ @@ -157,8 +157,13 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) /* Extend old last bitmap block - new blocks have been made available */ info = SB_AP_BITMAP(s) + bmap_nr - 1; - bh = info->bh; - get_bh(bh); + bh = reiserfs_read_bitmap_block(s, bmap_nr - 1); + if (!bh) { + int jerr = journal_end(&th, s, 10); + if (jerr) + return jerr; + return -EIO; + } reiserfs_prepare_for_journal(s, bh, 1); for (i = block_r; i < s->s_blocksize * 8; i++) @@ -172,8 +177,13 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) /* Correct new last bitmap block - It may not be full */ info = SB_AP_BITMAP(s) + bmap_nr_new - 1; - bh = info->bh; - get_bh(bh); + bh = reiserfs_read_bitmap_block(s, bmap_nr_new - 1); + if (!bh) { + int jerr = journal_end(&th, s, 10); + if (jerr) + return jerr; + return -EIO; + } reiserfs_prepare_for_journal(s, bh, 1); for (i = block_r_new; i < s->s_blocksize * 8; i++) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index c78e99e196f..c89aa233819 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -432,7 +432,6 @@ int remove_save_link(struct inode *inode, int truncate) static void reiserfs_put_super(struct super_block *s) { - int i; struct reiserfs_transaction_handle th; th.t_trans_id = 0; @@ -462,10 +461,7 @@ static void reiserfs_put_super(struct super_block *s) */ journal_release(&th, s); - for (i = 0; i < SB_BMAP_NR(s); i++) - brelse(SB_AP_BITMAP(s)[i].bh); - - vfree(SB_AP_BITMAP(s)); + reiserfs_free_bitmap_cache(s); brelse(SB_BUFFER_WITH_SB(s)); @@ -1344,7 +1340,6 @@ static int read_super_block(struct super_block *s, int offset) /* after journal replay, reread all bitmap and super blocks */ static int reread_meta_blocks(struct super_block *s) { - int i; ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))); wait_on_buffer(SB_BUFFER_WITH_SB(s)); if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) { @@ -1353,20 +1348,7 @@ static int reread_meta_blocks(struct super_block *s) return 1; } - for (i = 0; i < SB_BMAP_NR(s); i++) { - ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i].bh)); - wait_on_buffer(SB_AP_BITMAP(s)[i].bh); - if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) { - reiserfs_warning(s, - "reread_meta_blocks, error reading bitmap block number %d at %llu", - i, - (unsigned long long)SB_AP_BITMAP(s)[i]. - bh->b_blocknr); - return 1; - } - } return 0; - } ///////////////////////////////////////////////////// @@ -1547,7 +1529,6 @@ static int function2code(hashf_t func) static int reiserfs_fill_super(struct super_block *s, void *data, int silent) { struct inode *root_inode; - int j; struct reiserfs_transaction_handle th; int old_format = 0; unsigned long blocks; @@ -1793,19 +1774,17 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) if (jinit_done) { /* kill the commit thread, free journal ram */ journal_release_error(NULL, s); } - if (SB_DISK_SUPER_BLOCK(s)) { - for (j = 0; j < SB_BMAP_NR(s); j++) { - if (SB_AP_BITMAP(s)) - brelse(SB_AP_BITMAP(s)[j].bh); - } - vfree(SB_AP_BITMAP(s)); - } + + reiserfs_free_bitmap_cache(s); if (SB_BUFFER_WITH_SB(s)) brelse(SB_BUFFER_WITH_SB(s)); #ifdef CONFIG_QUOTA - for (j = 0; j < MAXQUOTAS; j++) { - kfree(sbi->s_qf_names[j]); - sbi->s_qf_names[j] = NULL; + { + int j; + for (j = 0; j < MAXQUOTAS; j++) { + kfree(sbi->s_qf_names[j]); + sbi->s_qf_names[j] = NULL; + } } #endif kfree(sbi); -- cgit v1.2.3 From 5a2618e6a972f305496daa257a56a09dd3acca29 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Sat, 30 Sep 2006 23:28:44 -0700 Subject: [PATCH] reiserfs: use generic_file_open for open() checks The other common disk-based file systems (I checked ext[23], xfs, jfs) check to ensure that opens of files > 2 GB fail unless O_LARGEFILE is specified. They check via generic_file_open or their own open routine. ReiserFS doesn't have an f_op->open defined, and as such, it's possible to open files > 2 GB without O_LARGEFILE. This patch adds the f_op->open member to conform with the expected behavior. Signed-off-by: Jeff Mahoney Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/file.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 3e08f7161a3..c11f6118c9c 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -1573,6 +1573,7 @@ const struct file_operations reiserfs_file_operations = { .compat_ioctl = reiserfs_compat_ioctl, #endif .mmap = generic_file_mmap, + .open = generic_file_open, .release = reiserfs_file_release, .fsync = reiserfs_sync_file, .sendfile = generic_file_sendfile, -- cgit v1.2.3 From 9ea0f9499d15c49df23e7aac4332d830c40e12d0 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Sat, 30 Sep 2006 23:28:45 -0700 Subject: [PATCH] reiserfs: eliminate minimum window size for bitmap searching When a file system becomes fragmented (using MythTV, for example), the bigalloc window searching ends up causing huge performance problems. In a file system presented by a user experiencing this bug, the file system was 90% free, but no 32-block free windows existed on the entire file system. This causes the allocator to scan the entire file system for each 128k write before backing down to searching for individual blocks. In the end, finding a contiguous window for all the blocks in a write is an advantageous special case, but one that can be found naturally when such a window exists anyway. This patch removes the bigalloc window searching, and has been proven to fix the test case described above. Signed-off-by: Jeff Mahoney Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/bitmap.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) (limited to 'fs') diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index cca1dbf5458..1bfae42117c 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -1034,7 +1034,6 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1; int passno = 0; int nr_allocated = 0; - int bigalloc = 0; determine_prealloc_size(hint); if (!hint->formatted_node) { @@ -1061,28 +1060,9 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start hint->preallocate = hint->prealloc_size = 0; } /* for unformatted nodes, force large allocations */ - bigalloc = amount_needed; } do { - /* in bigalloc mode, nr_allocated should stay zero until - * the entire allocation is filled - */ - if (unlikely(bigalloc && nr_allocated)) { - reiserfs_warning(s, "bigalloc is %d, nr_allocated %d\n", - bigalloc, nr_allocated); - /* reset things to a sane value */ - bigalloc = amount_needed - nr_allocated; - } - /* - * try pass 0 and pass 1 looking for a nice big - * contiguous allocation. Then reset and look - * for anything you can find. - */ - if (passno == 2 && bigalloc) { - passno = 0; - bigalloc = 0; - } switch (passno++) { case 0: /* Search from hint->search_start to end of disk */ start = hint->search_start; @@ -1120,8 +1100,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start new_blocknrs + nr_allocated, start, finish, - bigalloc ? - bigalloc : 1, + 1, amount_needed - nr_allocated, hint-> -- cgit v1.2.3 From 027445c37282bc1ed26add45e573ad2d3e4860a5 Mon Sep 17 00:00:00 2001 From: Badari Pulavarty Date: Sat, 30 Sep 2006 23:28:46 -0700 Subject: [PATCH] Vectorize aio_read/aio_write fileop methods This patch vectorizes aio_read() and aio_write() methods to prepare for collapsing all aio & vectored operations into one interface - which is aio_read()/aio_write(). Signed-off-by: Badari Pulavarty Signed-off-by: Christoph Hellwig Cc: Michael Holzheu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/aio.c | 15 +++++++++++---- fs/block_dev.c | 10 +--------- fs/cifs/cifsfs.c | 6 +++--- fs/ext3/file.c | 5 +++-- fs/nfs/direct.c | 26 +++++++++++++++++++------ fs/nfs/file.c | 34 +++++++++++++++++---------------- fs/ntfs/file.c | 8 +++----- fs/ocfs2/file.c | 28 +++++++++++++-------------- fs/read_write.c | 20 ++++++++++++++++---- fs/reiserfs/file.c | 4 ++-- fs/xfs/linux-2.6/xfs_file.c | 46 ++++++++++++++++++++++----------------------- 11 files changed, 113 insertions(+), 89 deletions(-) (limited to 'fs') diff --git a/fs/aio.c b/fs/aio.c index 950630187ac..27ff56540c7 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -15,6 +15,7 @@ #include #include #include +#include #define DEBUG 0 @@ -1315,8 +1316,11 @@ static ssize_t aio_pread(struct kiocb *iocb) ssize_t ret = 0; do { - ret = file->f_op->aio_read(iocb, iocb->ki_buf, - iocb->ki_left, iocb->ki_pos); + iocb->ki_inline_vec.iov_base = iocb->ki_buf; + iocb->ki_inline_vec.iov_len = iocb->ki_left; + + ret = file->f_op->aio_read(iocb, &iocb->ki_inline_vec, + 1, iocb->ki_pos); /* * Can't just depend on iocb->ki_left to determine * whether we are done. This may have been a short read. @@ -1349,8 +1353,11 @@ static ssize_t aio_pwrite(struct kiocb *iocb) ssize_t ret = 0; do { - ret = file->f_op->aio_write(iocb, iocb->ki_buf, - iocb->ki_left, iocb->ki_pos); + iocb->ki_inline_vec.iov_base = iocb->ki_buf; + iocb->ki_inline_vec.iov_len = iocb->ki_left; + + ret = file->f_op->aio_write(iocb, &iocb->ki_inline_vec, + 1, iocb->ki_pos); if (ret > 0) { iocb->ki_buf += ret; iocb->ki_left -= ret; diff --git a/fs/block_dev.c b/fs/block_dev.c index 0c361ea7e5a..8c819117310 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1162,14 +1162,6 @@ static ssize_t blkdev_file_write(struct file *file, const char __user *buf, return generic_file_write_nolock(file, &local_iov, 1, ppos); } -static ssize_t blkdev_file_aio_write(struct kiocb *iocb, const char __user *buf, - size_t count, loff_t pos) -{ - struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count }; - - return generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); -} - static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) { return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); @@ -1192,7 +1184,7 @@ const struct file_operations def_blk_fops = { .read = generic_file_read, .write = blkdev_file_write, .aio_read = generic_file_aio_read, - .aio_write = blkdev_file_aio_write, + .aio_write = generic_file_aio_write_nolock, .mmap = generic_file_mmap, .fsync = block_fsync, .unlocked_ioctl = block_ioctl, diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 22bcf4d7e7a..5abb42a7c53 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -492,13 +492,13 @@ static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov, return written; } -static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf, - size_t count, loff_t pos) +static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct inode *inode = iocb->ki_filp->f_dentry->d_inode; ssize_t written; - written = generic_file_aio_write(iocb, buf, count, pos); + written = generic_file_aio_write(iocb, iov, nr_segs, pos); if (!CIFS_I(inode)->clientCanCacheAll) filemap_fdatawrite(inode->i_mapping); return written; diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 74ff20f9d09..5c762457bc8 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -48,14 +48,15 @@ static int ext3_release_file (struct inode * inode, struct file * filp) } static ssize_t -ext3_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) +ext3_file_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_dentry->d_inode; ssize_t ret; int err; - ret = generic_file_aio_write(iocb, buf, count, pos); + ret = generic_file_aio_write(iocb, iov, nr_segs, pos); /* * Skip flushing if there was an error, or if nothing was written. diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 377839bed17..9f7f8b9ea1e 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -707,8 +707,8 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz /** * nfs_file_direct_read - file direct read operation for NFS files * @iocb: target I/O control block - * @buf: user's buffer into which to read data - * @count: number of bytes to read + * @iov: vector of user buffers into which to read data + * @nr_segs: size of iov vector * @pos: byte offset in file where reading starts * * We use this function for direct reads instead of calling @@ -725,17 +725,24 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz * client must read the updated atime from the server back into its * cache. */ -ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) +ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { ssize_t retval = -EINVAL; struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; + /* XXX: temporary */ + const char __user *buf = iov[0].iov_base; + size_t count = iov[0].iov_len; dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n", file->f_dentry->d_parent->d_name.name, file->f_dentry->d_name.name, (unsigned long) count, (long long) pos); + if (nr_segs != 1) + return -EINVAL; + if (count < 0) goto out; retval = -EFAULT; @@ -760,8 +767,8 @@ out: /** * nfs_file_direct_write - file direct write operation for NFS files * @iocb: target I/O control block - * @buf: user's buffer from which to write data - * @count: number of bytes to write + * @iov: vector of user buffers from which to write data + * @nr_segs: size of iov vector * @pos: byte offset in file where writing starts * * We use this function for direct writes instead of calling @@ -782,17 +789,24 @@ out: * Note that O_APPEND is not supported for NFS direct writes, as there * is no atomic O_APPEND write facility in the NFS protocol. */ -ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) +ssize_t nfs_file_direct_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { ssize_t retval; struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; + /* XXX: temporary */ + const char __user *buf = iov[0].iov_base; + size_t count = iov[0].iov_len; dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n", file->f_dentry->d_parent->d_name.name, file->f_dentry->d_name.name, (unsigned long) count, (long long) pos); + if (nr_segs != 1) + return -EINVAL; + retval = generic_write_checks(file, &pos, &count, 0); if (retval) goto out; diff --git a/fs/nfs/file.c b/fs/nfs/file.c index be997d64912..cc93865cea9 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -41,8 +41,10 @@ static int nfs_file_release(struct inode *, struct file *); static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); static int nfs_file_mmap(struct file *, struct vm_area_struct *); static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); -static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); -static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); +static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); +static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); static int nfs_file_flush(struct file *, fl_owner_t id); static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); static int nfs_check_flags(int flags); @@ -53,8 +55,8 @@ const struct file_operations nfs_file_operations = { .llseek = nfs_file_llseek, .read = do_sync_read, .write = do_sync_write, - .aio_read = nfs_file_read, - .aio_write = nfs_file_write, + .aio_read = nfs_file_read, + .aio_write = nfs_file_write, .mmap = nfs_file_mmap, .open = nfs_file_open, .flush = nfs_file_flush, @@ -196,15 +198,17 @@ nfs_file_flush(struct file *file, fl_owner_t id) } static ssize_t -nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) +nfs_file_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct dentry * dentry = iocb->ki_filp->f_dentry; struct inode * inode = dentry->d_inode; ssize_t result; + size_t count = iov_length(iov, nr_segs); #ifdef CONFIG_NFS_DIRECTIO if (iocb->ki_filp->f_flags & O_DIRECT) - return nfs_file_direct_read(iocb, buf, count, pos); + return nfs_file_direct_read(iocb, iov, nr_segs, pos); #endif dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n", @@ -214,7 +218,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count); if (!result) - result = generic_file_aio_read(iocb, buf, count, pos); + result = generic_file_aio_read(iocb, iov, nr_segs, pos); return result; } @@ -336,24 +340,22 @@ const struct address_space_operations nfs_file_aops = { #endif }; -/* - * Write to a file (through the page cache). - */ -static ssize_t -nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) +static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct dentry * dentry = iocb->ki_filp->f_dentry; struct inode * inode = dentry->d_inode; ssize_t result; + size_t count = iov_length(iov, nr_segs); #ifdef CONFIG_NFS_DIRECTIO if (iocb->ki_filp->f_flags & O_DIRECT) - return nfs_file_direct_write(iocb, buf, count, pos); + return nfs_file_direct_write(iocb, iov, nr_segs, pos); #endif - dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n", + dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%Ld)\n", dentry->d_parent->d_name.name, dentry->d_name.name, - inode->i_ino, (unsigned long) count, (unsigned long) pos); + inode->i_ino, (unsigned long) count, (long long) pos); result = -EBUSY; if (IS_SWAPFILE(inode)) @@ -372,7 +374,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t goto out; nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); - result = generic_file_aio_write(iocb, buf, count, pos); + result = generic_file_aio_write(iocb, iov, nr_segs, pos); out: return result; diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 585a79d39c9..0c46f5c86b7 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -2176,20 +2176,18 @@ out: /** * ntfs_file_aio_write - */ -static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const char __user *buf, - size_t count, loff_t pos) +static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; struct inode *inode = mapping->host; ssize_t ret; - struct iovec local_iov = { .iov_base = (void __user *)buf, - .iov_len = count }; BUG_ON(iocb->ki_pos != pos); mutex_lock(&inode->i_mutex); - ret = ntfs_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); + ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos); mutex_unlock(&inode->i_mutex); if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) { int err = sync_page_range(inode, mapping, pos, ret); diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 2bbfa17090c..d9ba0a931a0 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -961,25 +961,23 @@ static inline int ocfs2_write_should_remove_suid(struct inode *inode) } static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, - const char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { - struct iovec local_iov = { .iov_base = (void __user *)buf, - .iov_len = count }; int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0; u32 clusters; struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; loff_t newsize, saved_pos; - mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, - (unsigned int)count, + mlog_entry("(0x%p, %u, '%.*s')\n", filp, + (unsigned int)nr_segs, filp->f_dentry->d_name.len, filp->f_dentry->d_name.name); /* happy write of zero bytes */ - if (count == 0) + if (iocb->ki_left == 0) return 0; if (!inode) { @@ -1048,7 +1046,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, } else { saved_pos = iocb->ki_pos; } - newsize = count + saved_pos; + newsize = iocb->ki_left + saved_pos; mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", (long long) saved_pos, (long long) newsize, @@ -1081,7 +1079,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, if (!clusters) break; - ret = ocfs2_extend_file(inode, NULL, newsize, count); + ret = ocfs2_extend_file(inode, NULL, newsize, iocb->ki_left); if (ret < 0) { if (ret != -ENOSPC) mlog_errno(ret); @@ -1098,7 +1096,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, /* communicate with ocfs2_dio_end_io */ ocfs2_iocb_set_rw_locked(iocb); - ret = generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); + ret = generic_file_aio_write_nolock(iocb, iov, nr_segs, iocb->ki_pos); /* buffered aio wouldn't have proper lock coverage today */ BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); @@ -1132,16 +1130,16 @@ out: } static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, - char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { int ret = 0, rw_level = -1, have_alloc_sem = 0; struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; - mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, - (unsigned int)count, + mlog_entry("(0x%p, %u, '%.*s')\n", filp, + (unsigned int)nr_segs, filp->f_dentry->d_name.len, filp->f_dentry->d_name.name); @@ -1185,7 +1183,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, } ocfs2_meta_unlock(inode, 0); - ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos); + ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); if (ret == -EINVAL) mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); diff --git a/fs/read_write.c b/fs/read_write.c index d4cb3183c99..679dd535380 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -227,14 +227,20 @@ static void wait_on_retry_sync_kiocb(struct kiocb *iocb) ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) { + struct iovec iov = { .iov_base = buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; - while (-EIOCBRETRY == - (ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos))) + kiocb.ki_left = len; + + for (;;) { + ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); + if (ret != -EIOCBRETRY) + break; wait_on_retry_sync_kiocb(&kiocb); + } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); @@ -279,14 +285,20 @@ EXPORT_SYMBOL(vfs_read); ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { + struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; struct kiocb kiocb; ssize_t ret; init_sync_kiocb(&kiocb, filp); kiocb.ki_pos = *ppos; - while (-EIOCBRETRY == - (ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos))) + kiocb.ki_left = len; + + for (;;) { + ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); + if (ret != -EIOCBRETRY) + break; wait_on_retry_sync_kiocb(&kiocb); + } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index c11f6118c9c..41f24369e47 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -1334,7 +1334,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t if (err) return err; } - result = generic_file_write(file, buf, count, ppos); + result = do_sync_write(file, buf, count, ppos); if (after_file_end) { /* Now update i_size and remove the savelink */ struct reiserfs_transaction_handle th; @@ -1566,7 +1566,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t } const struct file_operations reiserfs_file_operations = { - .read = generic_file_read, + .read = do_sync_read, .write = reiserfs_file_write, .ioctl = reiserfs_ioctl, #ifdef CONFIG_COMPAT diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 41cfcba7ce4..4737971c6a3 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -49,50 +49,49 @@ static struct vm_operations_struct xfs_dmapi_file_vm_ops; STATIC inline ssize_t __xfs_file_read( struct kiocb *iocb, - char __user *buf, + const struct iovec *iov, + unsigned long nr_segs, int ioflags, - size_t count, loff_t pos) { - struct iovec iov = {buf, count}; struct file *file = iocb->ki_filp; bhv_vnode_t *vp = vn_from_inode(file->f_dentry->d_inode); BUG_ON(iocb->ki_pos != pos); if (unlikely(file->f_flags & O_DIRECT)) ioflags |= IO_ISDIRECT; - return bhv_vop_read(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL); + return bhv_vop_read(vp, iocb, iov, nr_segs, &iocb->ki_pos, + ioflags, NULL); } STATIC ssize_t xfs_file_aio_read( struct kiocb *iocb, - char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { - return __xfs_file_read(iocb, buf, IO_ISAIO, count, pos); + return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO, pos); } STATIC ssize_t xfs_file_aio_read_invis( struct kiocb *iocb, - char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { - return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); + return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); } STATIC inline ssize_t __xfs_file_write( - struct kiocb *iocb, - const char __user *buf, - int ioflags, - size_t count, - loff_t pos) + struct kiocb *iocb, + const struct iovec *iov, + unsigned long nr_segs, + int ioflags, + loff_t pos) { - struct iovec iov = {(void __user *)buf, count}; struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; bhv_vnode_t *vp = vn_from_inode(inode); @@ -100,27 +99,28 @@ __xfs_file_write( BUG_ON(iocb->ki_pos != pos); if (unlikely(file->f_flags & O_DIRECT)) ioflags |= IO_ISDIRECT; - return bhv_vop_write(vp, iocb, &iov, 1, &iocb->ki_pos, ioflags, NULL); + return bhv_vop_write(vp, iocb, iov, nr_segs, &iocb->ki_pos, + ioflags, NULL); } STATIC ssize_t xfs_file_aio_write( struct kiocb *iocb, - const char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { - return __xfs_file_write(iocb, buf, IO_ISAIO, count, pos); + return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO, pos); } STATIC ssize_t xfs_file_aio_write_invis( struct kiocb *iocb, - const char __user *buf, - size_t count, + const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { - return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); + return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); } STATIC inline ssize_t -- cgit v1.2.3 From ee0b3e671baff681d69fbf0db33b47603c0a8280 Mon Sep 17 00:00:00 2001 From: Badari Pulavarty Date: Sat, 30 Sep 2006 23:28:47 -0700 Subject: [PATCH] Remove readv/writev methods and use aio_read/aio_write instead This patch removes readv() and writev() methods and replaces them with aio_read()/aio_write() methods. Signed-off-by: Badari Pulavarty Signed-off-by: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/bad_inode.c | 2 - fs/block_dev.c | 2 - fs/cifs/cifsfs.c | 16 ------- fs/compat.c | 44 +++++-------------- fs/ext2/file.c | 2 - fs/ext3/file.c | 2 - fs/fat/file.c | 2 - fs/fuse/dev.c | 37 +++++----------- fs/hostfs/hostfs_kern.c | 2 - fs/jfs/file.c | 2 - fs/ntfs/file.c | 2 - fs/pipe.c | 59 ++++++++++---------------- fs/read_write.c | 101 +++++++++++++++++++++++++++++--------------- fs/read_write.h | 14 ++++++ fs/xfs/linux-2.6/xfs_file.c | 94 ----------------------------------------- 15 files changed, 124 insertions(+), 257 deletions(-) create mode 100644 fs/read_write.h (limited to 'fs') diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 80599ae3396..34e6d7b220c 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c @@ -40,8 +40,6 @@ static const struct file_operations bad_file_ops = .aio_fsync = EIO_ERROR, .fasync = EIO_ERROR, .lock = EIO_ERROR, - .readv = EIO_ERROR, - .writev = EIO_ERROR, .sendfile = EIO_ERROR, .sendpage = EIO_ERROR, .get_unmapped_area = EIO_ERROR, diff --git a/fs/block_dev.c b/fs/block_dev.c index 8c819117310..0f143094ef1 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1191,8 +1191,6 @@ const struct file_operations def_blk_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = compat_blkdev_ioctl, #endif - .readv = generic_file_readv, - .writev = generic_file_write_nolock, .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5abb42a7c53..c00c654f2e1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -480,18 +480,6 @@ cifs_get_sb(struct file_system_type *fs_type, return simple_set_mnt(mnt, sb); } -static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov, - unsigned long nr_segs, loff_t *ppos) -{ - struct inode *inode = file->f_dentry->d_inode; - ssize_t written; - - written = generic_file_writev(file, iov, nr_segs, ppos); - if (!CIFS_I(inode)->clientCanCacheAll) - filemap_fdatawrite(inode->i_mapping); - return written; -} - static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { @@ -577,8 +565,6 @@ struct inode_operations cifs_symlink_inode_ops = { const struct file_operations cifs_file_ops = { .read = do_sync_read, .write = do_sync_write, - .readv = generic_file_readv, - .writev = cifs_file_writev, .aio_read = generic_file_aio_read, .aio_write = cifs_file_aio_write, .open = cifs_open, @@ -620,8 +606,6 @@ const struct file_operations cifs_file_direct_ops = { const struct file_operations cifs_file_nobrl_ops = { .read = do_sync_read, .write = do_sync_write, - .readv = generic_file_readv, - .writev = cifs_file_writev, .aio_read = generic_file_aio_read, .aio_write = cifs_file_aio_write, .open = cifs_open, diff --git a/fs/compat.c b/fs/compat.c index 122b4e3992b..6b90bf35f61 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -70,6 +70,8 @@ int compat_printk(const char *fmt, ...) return ret; } +#include "read_write.h" + /* * Not all architectures have sys_utime, so implement this in terms * of sys_utimes. @@ -1149,9 +1151,6 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, const struct compat_iovec __user *uvector, unsigned long nr_segs, loff_t *pos) { - typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); - typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *); - compat_ssize_t tot_len; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov=iovstack, *vector; @@ -1234,39 +1233,18 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, fnv = NULL; if (type == READ) { fn = file->f_op->read; - fnv = file->f_op->readv; + fnv = file->f_op->aio_read; } else { fn = (io_fn_t)file->f_op->write; - fnv = file->f_op->writev; - } - if (fnv) { - ret = fnv(file, iov, nr_segs, pos); - goto out; + fnv = file->f_op->aio_write; } - /* Do it by hand, with file-ops */ - ret = 0; - vector = iov; - while (nr_segs > 0) { - void __user * base; - size_t len; - ssize_t nr; - - base = vector->iov_base; - len = vector->iov_len; - vector++; - nr_segs--; - - nr = fn(file, base, len, pos); + if (fnv) + ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, + pos, fnv); + else + ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); - if (nr < 0) { - if (!ret) ret = nr; - break; - } - ret += nr; - if (nr != len) - break; - } out: if (iov != iovstack) kfree(iov); @@ -1294,7 +1272,7 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsign goto out; ret = -EINVAL; - if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) + if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) goto out; ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos); @@ -1317,7 +1295,7 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsig goto out; ret = -EINVAL; - if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) + if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) goto out; ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos); diff --git a/fs/ext2/file.c b/fs/ext2/file.c index e8bbed9dd26..e893e2be9ed 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -53,8 +53,6 @@ const struct file_operations ext2_file_operations = { .open = generic_file_open, .release = ext2_release_file, .fsync = ext2_sync_file, - .readv = generic_file_readv, - .writev = generic_file_writev, .sendfile = generic_file_sendfile, .splice_read = generic_file_splice_read, .splice_write = generic_file_splice_write, diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 5c762457bc8..e96c388047e 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -112,8 +112,6 @@ const struct file_operations ext3_file_operations = { .write = do_sync_write, .aio_read = generic_file_aio_read, .aio_write = ext3_file_write, - .readv = generic_file_readv, - .writev = generic_file_writev, .ioctl = ext3_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = ext3_compat_ioctl, diff --git a/fs/fat/file.c b/fs/fat/file.c index d50fc47169c..f4b8f8b3fbd 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -127,8 +127,6 @@ const struct file_operations fat_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .write = do_sync_write, - .readv = generic_file_readv, - .writev = generic_file_writev, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 4fc557c40cc..66571eafbb1 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -680,14 +680,15 @@ static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req, * request_end(). Otherwise add it to the processing list, and set * the 'sent' flag. */ -static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, - unsigned long nr_segs, loff_t *off) +static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { int err; struct fuse_req *req; struct fuse_in *in; struct fuse_copy_state cs; unsigned reqsize; + struct file *file = iocb->ki_filp; struct fuse_conn *fc = fuse_get_conn(file); if (!fc) return -EPERM; @@ -761,15 +762,6 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov, return err; } -static ssize_t fuse_dev_read(struct file *file, char __user *buf, - size_t nbytes, loff_t *off) -{ - struct iovec iov; - iov.iov_len = nbytes; - iov.iov_base = buf; - return fuse_dev_readv(file, &iov, 1, off); -} - /* Look up request on processing list by unique ID */ static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique) { @@ -814,15 +806,15 @@ static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out, * it from the list and copy the rest of the buffer to the request. * The request is finished by calling request_end() */ -static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, - unsigned long nr_segs, loff_t *off) +static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { int err; unsigned nbytes = iov_length(iov, nr_segs); struct fuse_req *req; struct fuse_out_header oh; struct fuse_copy_state cs; - struct fuse_conn *fc = fuse_get_conn(file); + struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp); if (!fc) return -EPERM; @@ -898,15 +890,6 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov, return err; } -static ssize_t fuse_dev_write(struct file *file, const char __user *buf, - size_t nbytes, loff_t *off) -{ - struct iovec iov; - iov.iov_len = nbytes; - iov.iov_base = (char __user *) buf; - return fuse_dev_writev(file, &iov, 1, off); -} - static unsigned fuse_dev_poll(struct file *file, poll_table *wait) { unsigned mask = POLLOUT | POLLWRNORM; @@ -1041,10 +1024,10 @@ static int fuse_dev_fasync(int fd, struct file *file, int on) const struct file_operations fuse_dev_operations = { .owner = THIS_MODULE, .llseek = no_llseek, - .read = fuse_dev_read, - .readv = fuse_dev_readv, - .write = fuse_dev_write, - .writev = fuse_dev_writev, + .read = do_sync_read, + .aio_read = fuse_dev_read, + .write = do_sync_write, + .aio_write = fuse_dev_write, .poll = fuse_dev_poll, .release = fuse_dev_release, .fasync = fuse_dev_fasync, diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 322e876c35e..4908c38a588 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -389,8 +389,6 @@ static const struct file_operations hostfs_file_fops = { .sendfile = generic_file_sendfile, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, - .readv = generic_file_readv, - .writev = generic_file_writev, .write = generic_file_write, .mmap = generic_file_mmap, .open = hostfs_file_open, diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 1c9745be5ad..f535f2911c1 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -108,8 +108,6 @@ const struct file_operations jfs_file_operations = { .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, - .readv = generic_file_readv, - .writev = generic_file_writev, .sendfile = generic_file_sendfile, .fsync = jfs_fsync, .release = jfs_release, diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 0c46f5c86b7..2f9b5a0953f 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -2298,11 +2298,9 @@ const struct file_operations ntfs_file_ops = { .llseek = generic_file_llseek, /* Seek inside file. */ .read = generic_file_read, /* Read from file. */ .aio_read = generic_file_aio_read, /* Async read from file. */ - .readv = generic_file_readv, /* Read from file. */ #ifdef NTFS_RW .write = ntfs_file_write, /* Write to file. */ .aio_write = ntfs_file_aio_write, /* Async write to file. */ - .writev = ntfs_file_writev, /* Write to file. */ /*.release = ,*/ /* Last file is closed. See fs/ext2/file.c:: ext2_release_file() for diff --git a/fs/pipe.c b/fs/pipe.c index f3b6f71e9d0..2e60e1c8815 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -218,9 +218,10 @@ static struct pipe_buf_operations anon_pipe_buf_ops = { }; static ssize_t -pipe_readv(struct file *filp, const struct iovec *_iov, - unsigned long nr_segs, loff_t *ppos) +pipe_read(struct kiocb *iocb, const struct iovec *_iov, + unsigned long nr_segs, loff_t pos) { + struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; struct pipe_inode_info *pipe; int do_wakeup; @@ -330,17 +331,10 @@ redo: } static ssize_t -pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) -{ - struct iovec iov = { .iov_base = buf, .iov_len = count }; - - return pipe_readv(filp, &iov, 1, ppos); -} - -static ssize_t -pipe_writev(struct file *filp, const struct iovec *_iov, - unsigned long nr_segs, loff_t *ppos) +pipe_write(struct kiocb *iocb, const struct iovec *_iov, + unsigned long nr_segs, loff_t ppos) { + struct file *filp = iocb->ki_filp; struct inode *inode = filp->f_dentry->d_inode; struct pipe_inode_info *pipe; ssize_t ret; @@ -509,15 +503,6 @@ out: return ret; } -static ssize_t -pipe_write(struct file *filp, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count }; - - return pipe_writev(filp, &iov, 1, ppos); -} - static ssize_t bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { @@ -736,8 +721,8 @@ pipe_rdwr_open(struct inode *inode, struct file *filp) */ const struct file_operations read_fifo_fops = { .llseek = no_llseek, - .read = pipe_read, - .readv = pipe_readv, + .read = do_sync_read, + .aio_read = pipe_read, .write = bad_pipe_w, .poll = pipe_poll, .ioctl = pipe_ioctl, @@ -749,8 +734,8 @@ const struct file_operations read_fifo_fops = { const struct file_operations write_fifo_fops = { .llseek = no_llseek, .read = bad_pipe_r, - .write = pipe_write, - .writev = pipe_writev, + .write = do_sync_write, + .aio_write = pipe_write, .poll = pipe_poll, .ioctl = pipe_ioctl, .open = pipe_write_open, @@ -760,10 +745,10 @@ const struct file_operations write_fifo_fops = { const struct file_operations rdwr_fifo_fops = { .llseek = no_llseek, - .read = pipe_read, - .readv = pipe_readv, - .write = pipe_write, - .writev = pipe_writev, + .read = do_sync_read, + .aio_read = pipe_read, + .write = do_sync_write, + .aio_write = pipe_write, .poll = pipe_poll, .ioctl = pipe_ioctl, .open = pipe_rdwr_open, @@ -773,8 +758,8 @@ const struct file_operations rdwr_fifo_fops = { static struct file_operations read_pipe_fops = { .llseek = no_llseek, - .read = pipe_read, - .readv = pipe_readv, + .read = do_sync_read, + .aio_read = pipe_read, .write = bad_pipe_w, .poll = pipe_poll, .ioctl = pipe_ioctl, @@ -786,8 +771,8 @@ static struct file_operations read_pipe_fops = { static struct file_operations write_pipe_fops = { .llseek = no_llseek, .read = bad_pipe_r, - .write = pipe_write, - .writev = pipe_writev, + .write = do_sync_write, + .aio_write = pipe_write, .poll = pipe_poll, .ioctl = pipe_ioctl, .open = pipe_write_open, @@ -797,10 +782,10 @@ static struct file_operations write_pipe_fops = { static struct file_operations rdwr_pipe_fops = { .llseek = no_llseek, - .read = pipe_read, - .readv = pipe_readv, - .write = pipe_write, - .writev = pipe_writev, + .read = do_sync_read, + .aio_read = pipe_read, + .write = do_sync_write, + .aio_write = pipe_write, .poll = pipe_poll, .ioctl = pipe_ioctl, .open = pipe_rdwr_open, diff --git a/fs/read_write.c b/fs/read_write.c index 679dd535380..32d54cca9bd 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -15,6 +15,7 @@ #include #include #include +#include "read_write.h" #include #include @@ -450,6 +451,62 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */ +ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, + unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn) +{ + struct kiocb kiocb; + ssize_t ret; + + init_sync_kiocb(&kiocb, filp); + kiocb.ki_pos = *ppos; + kiocb.ki_left = len; + kiocb.ki_nbytes = len; + + for (;;) { + ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos); + if (ret != -EIOCBRETRY) + break; + wait_on_retry_sync_kiocb(&kiocb); + } + + if (ret == -EIOCBQUEUED) + ret = wait_on_sync_kiocb(&kiocb); + *ppos = kiocb.ki_pos; + return ret; +} + +/* Do it by hand, with file-ops */ +ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, + unsigned long nr_segs, loff_t *ppos, io_fn_t fn) +{ + struct iovec *vector = iov; + ssize_t ret = 0; + + while (nr_segs > 0) { + void __user *base; + size_t len; + ssize_t nr; + + base = vector->iov_base; + len = vector->iov_len; + vector++; + nr_segs--; + + nr = fn(filp, base, len, ppos); + + if (nr < 0) { + if (!ret) + ret = nr; + break; + } + ret += nr; + if (nr != len) + break; + } + + return ret; +} + /* A write operation does a read from user space and vice versa */ #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) @@ -457,12 +514,9 @@ static ssize_t do_readv_writev(int type, struct file *file, const struct iovec __user * uvector, unsigned long nr_segs, loff_t *pos) { - typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); - typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *); - size_t tot_len; struct iovec iovstack[UIO_FASTIOV]; - struct iovec *iov=iovstack, *vector; + struct iovec *iov = iovstack; ssize_t ret; int seg; io_fn_t fn; @@ -532,39 +586,18 @@ static ssize_t do_readv_writev(int type, struct file *file, fnv = NULL; if (type == READ) { fn = file->f_op->read; - fnv = file->f_op->readv; + fnv = file->f_op->aio_read; } else { fn = (io_fn_t)file->f_op->write; - fnv = file->f_op->writev; - } - if (fnv) { - ret = fnv(file, iov, nr_segs, pos); - goto out; + fnv = file->f_op->aio_write; } - /* Do it by hand, with file-ops */ - ret = 0; - vector = iov; - while (nr_segs > 0) { - void __user * base; - size_t len; - ssize_t nr; - - base = vector->iov_base; - len = vector->iov_len; - vector++; - nr_segs--; - - nr = fn(file, base, len, pos); + if (fnv) + ret = do_sync_readv_writev(file, iov, nr_segs, tot_len, + pos, fnv); + else + ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn); - if (nr < 0) { - if (!ret) ret = nr; - break; - } - ret += nr; - if (nr != len) - break; - } out: if (iov != iovstack) kfree(iov); @@ -585,7 +618,7 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, { if (!(file->f_mode & FMODE_READ)) return -EBADF; - if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) + if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) return -EINVAL; return do_readv_writev(READ, file, vec, vlen, pos); @@ -598,7 +631,7 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, { if (!(file->f_mode & FMODE_WRITE)) return -EBADF; - if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) + if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) return -EINVAL; return do_readv_writev(WRITE, file, vec, vlen, pos); diff --git a/fs/read_write.h b/fs/read_write.h new file mode 100644 index 00000000000..d07b954c6e0 --- /dev/null +++ b/fs/read_write.h @@ -0,0 +1,14 @@ +/* + * This file is only for sharing some helpers from read_write.c with compat.c. + * Don't use anywhere else. + */ + + +typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *); +typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *, + unsigned long, loff_t); + +ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov, + unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn); +ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, + unsigned long nr_segs, loff_t *ppos, io_fn_t fn); diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 4737971c6a3..d93d8dd1958 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c @@ -123,96 +123,6 @@ xfs_file_aio_write_invis( return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos); } -STATIC inline ssize_t -__xfs_file_readv( - struct file *file, - const struct iovec *iov, - int ioflags, - unsigned long nr_segs, - loff_t *ppos) -{ - struct inode *inode = file->f_mapping->host; - bhv_vnode_t *vp = vn_from_inode(inode); - struct kiocb kiocb; - ssize_t rval; - - init_sync_kiocb(&kiocb, file); - kiocb.ki_pos = *ppos; - - if (unlikely(file->f_flags & O_DIRECT)) - ioflags |= IO_ISDIRECT; - rval = bhv_vop_read(vp, &kiocb, iov, nr_segs, - &kiocb.ki_pos, ioflags, NULL); - - *ppos = kiocb.ki_pos; - return rval; -} - -STATIC ssize_t -xfs_file_readv( - struct file *file, - const struct iovec *iov, - unsigned long nr_segs, - loff_t *ppos) -{ - return __xfs_file_readv(file, iov, 0, nr_segs, ppos); -} - -STATIC ssize_t -xfs_file_readv_invis( - struct file *file, - const struct iovec *iov, - unsigned long nr_segs, - loff_t *ppos) -{ - return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos); -} - -STATIC inline ssize_t -__xfs_file_writev( - struct file *file, - const struct iovec *iov, - int ioflags, - unsigned long nr_segs, - loff_t *ppos) -{ - struct inode *inode = file->f_mapping->host; - bhv_vnode_t *vp = vn_from_inode(inode); - struct kiocb kiocb; - ssize_t rval; - - init_sync_kiocb(&kiocb, file); - kiocb.ki_pos = *ppos; - if (unlikely(file->f_flags & O_DIRECT)) - ioflags |= IO_ISDIRECT; - - rval = bhv_vop_write(vp, &kiocb, iov, nr_segs, - &kiocb.ki_pos, ioflags, NULL); - - *ppos = kiocb.ki_pos; - return rval; -} - -STATIC ssize_t -xfs_file_writev( - struct file *file, - const struct iovec *iov, - unsigned long nr_segs, - loff_t *ppos) -{ - return __xfs_file_writev(file, iov, 0, nr_segs, ppos); -} - -STATIC ssize_t -xfs_file_writev_invis( - struct file *file, - const struct iovec *iov, - unsigned long nr_segs, - loff_t *ppos) -{ - return __xfs_file_writev(file, iov, IO_INVIS, nr_segs, ppos); -} - STATIC ssize_t xfs_file_sendfile( struct file *filp, @@ -540,8 +450,6 @@ const struct file_operations xfs_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .write = do_sync_write, - .readv = xfs_file_readv, - .writev = xfs_file_writev, .aio_read = xfs_file_aio_read, .aio_write = xfs_file_aio_write, .sendfile = xfs_file_sendfile, @@ -565,8 +473,6 @@ const struct file_operations xfs_invis_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .write = do_sync_write, - .readv = xfs_file_readv_invis, - .writev = xfs_file_writev_invis, .aio_read = xfs_file_aio_read_invis, .aio_write = xfs_file_aio_write_invis, .sendfile = xfs_file_sendfile_invis, -- cgit v1.2.3 From 543ade1fc901db4c3dbe9fb27241fb977f1f3eea Mon Sep 17 00:00:00 2001 From: Badari Pulavarty Date: Sat, 30 Sep 2006 23:28:48 -0700 Subject: [PATCH] Streamline generic_file_* interfaces and filemap cleanups This patch cleans up generic_file_*_read/write() interfaces. Christoph Hellwig gave me the idea for this clean ups. In a nutshell, all filesystems should set .aio_read/.aio_write methods and use do_sync_read/ do_sync_write() as their .read/.write methods. This allows us to cleanup all variants of generic_file_* routines. Final available interfaces: generic_file_aio_read() - read handler generic_file_aio_write() - write handler generic_file_aio_write_nolock() - no lock write handler __generic_file_aio_write_nolock() - internal worker routine Signed-off-by: Badari Pulavarty Signed-off-by: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/adfs/file.c | 6 ++++-- fs/affs/file.c | 6 ++++-- fs/bfs/file.c | 6 ++++-- fs/block_dev.c | 12 ++---------- fs/ext2/file.c | 4 ++-- fs/fuse/file.c | 6 ++++-- fs/hfs/inode.c | 6 ++++-- fs/hfsplus/inode.c | 6 ++++-- fs/hostfs/hostfs_kern.c | 4 ++-- fs/hpfs/file.c | 6 ++++-- fs/jffs/inode-v23.c | 6 ++++-- fs/jffs2/file.c | 6 ++++-- fs/jfs/file.c | 4 ++-- fs/minix/file.c | 6 ++++-- fs/ntfs/file.c | 2 +- fs/qnx4/file.c | 6 ++++-- fs/ramfs/file-mmu.c | 6 ++++-- fs/ramfs/file-nommu.c | 6 ++++-- fs/read_write.c | 3 ++- fs/smbfs/file.c | 24 +++++++++++++++--------- fs/sysv/file.c | 6 ++++-- fs/udf/file.c | 16 ++++++++++------ fs/ufs/file.c | 6 ++++-- fs/xfs/linux-2.6/xfs_lrw.c | 4 +++- 24 files changed, 99 insertions(+), 64 deletions(-) (limited to 'fs') diff --git a/fs/adfs/file.c b/fs/adfs/file.c index 1014b9f2117..6101ea679cb 100644 --- a/fs/adfs/file.c +++ b/fs/adfs/file.c @@ -27,10 +27,12 @@ const struct file_operations adfs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .mmap = generic_file_mmap, .fsync = file_fsync, - .write = generic_file_write, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .sendfile = generic_file_sendfile, }; diff --git a/fs/affs/file.c b/fs/affs/file.c index 3de8590e4f6..05b5e22de75 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -27,8 +27,10 @@ static int affs_file_release(struct inode *inode, struct file *filp); const struct file_operations affs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .open = affs_file_open, .release = affs_file_release, diff --git a/fs/bfs/file.c b/fs/bfs/file.c index 3d5aca28a0a..a9164a87f8d 100644 --- a/fs/bfs/file.c +++ b/fs/bfs/file.c @@ -19,8 +19,10 @@ const struct file_operations bfs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .sendfile = generic_file_sendfile, }; diff --git a/fs/block_dev.c b/fs/block_dev.c index 0f143094ef1..bc8f27cc448 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1154,14 +1154,6 @@ static int blkdev_close(struct inode * inode, struct file * filp) return blkdev_put(bdev); } -static ssize_t blkdev_file_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count }; - - return generic_file_write_nolock(file, &local_iov, 1, ppos); -} - static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) { return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); @@ -1181,8 +1173,8 @@ const struct file_operations def_blk_fops = { .open = blkdev_open, .release = blkdev_close, .llseek = block_llseek, - .read = generic_file_read, - .write = blkdev_file_write, + .read = do_sync_read, + .write = do_sync_write, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write_nolock, .mmap = generic_file_mmap, diff --git a/fs/ext2/file.c b/fs/ext2/file.c index e893e2be9ed..2dba473c524 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -41,8 +41,8 @@ static int ext2_release_file (struct inode * inode, struct file * filp) */ const struct file_operations ext2_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .write = do_sync_write, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .ioctl = ext2_ioctl, diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 5c4fcd1dbf5..183626868ee 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -753,8 +753,10 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) static const struct file_operations fuse_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = fuse_file_mmap, .open = fuse_open, .flush = fuse_flush, diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index d05641c35fc..02f5573e034 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -601,8 +601,10 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr) static const struct file_operations hfs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .sendfile = generic_file_sendfile, .fsync = file_fsync, diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 0eb1a609266..9e367524963 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -282,8 +282,10 @@ static struct inode_operations hfsplus_file_inode_operations = { static const struct file_operations hfsplus_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .sendfile = generic_file_sendfile, .fsync = file_fsync, diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 4908c38a588..b6bd33ca373 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -385,11 +385,11 @@ int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) static const struct file_operations hostfs_file_fops = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, .sendfile = generic_file_sendfile, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, - .write = generic_file_write, + .write = do_sync_write, .mmap = generic_file_mmap, .open = hostfs_file_open, .release = NULL, diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index d9eb19b7b8a..8b94d24855f 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -113,7 +113,7 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf, { ssize_t retval; - retval = generic_file_write(file, buf, count, ppos); + retval = do_sync_write(file, buf, count, ppos); if (retval > 0) hpfs_i(file->f_dentry->d_inode)->i_dirty = 1; return retval; @@ -122,8 +122,10 @@ static ssize_t hpfs_file_write(struct file *file, const char __user *buf, const struct file_operations hpfs_file_ops = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .write = hpfs_file_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .release = hpfs_file_release, .fsync = hpfs_file_fsync, diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index f5cf9c93e24..068ef0de8de 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c @@ -1632,8 +1632,10 @@ static const struct file_operations jffs_file_operations = { .open = generic_file_open, .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .ioctl = jffs_ioctl, .mmap = generic_file_readonly_mmap, .fsync = jffs_fsync, diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 3ed6e3e120b..242875f77cb 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -42,8 +42,10 @@ const struct file_operations jffs2_file_operations = { .llseek = generic_file_llseek, .open = generic_file_open, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .ioctl = jffs2_ioctl, .mmap = generic_file_readonly_mmap, .fsync = jffs2_fsync, diff --git a/fs/jfs/file.c b/fs/jfs/file.c index f535f2911c1..976e90dc2d1 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -103,8 +103,8 @@ struct inode_operations jfs_file_inode_operations = { const struct file_operations jfs_file_operations = { .open = jfs_open, .llseek = generic_file_llseek, - .write = generic_file_write, - .read = generic_file_read, + .write = do_sync_write, + .read = do_sync_read, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, diff --git a/fs/minix/file.c b/fs/minix/file.c index 420b32882a1..40eac2e60d2 100644 --- a/fs/minix/file.c +++ b/fs/minix/file.c @@ -17,8 +17,10 @@ int minix_sync_file(struct file *, struct dentry *, int); const struct file_operations minix_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = minix_sync_file, .sendfile = generic_file_sendfile, diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index 2f9b5a0953f..ae2fe0016d2 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -2296,7 +2296,7 @@ static int ntfs_file_fsync(struct file *filp, struct dentry *dentry, const struct file_operations ntfs_file_ops = { .llseek = generic_file_llseek, /* Seek inside file. */ - .read = generic_file_read, /* Read from file. */ + .read = do_sync_read, /* Read from file. */ .aio_read = generic_file_aio_read, /* Async read from file. */ #ifdef NTFS_RW .write = ntfs_file_write, /* Write to file. */ diff --git a/fs/qnx4/file.c b/fs/qnx4/file.c index 62af4b1348b..467e5ac7280 100644 --- a/fs/qnx4/file.c +++ b/fs/qnx4/file.c @@ -22,11 +22,13 @@ const struct file_operations qnx4_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .mmap = generic_file_mmap, .sendfile = generic_file_sendfile, #ifdef CONFIG_QNX4FS_RW - .write = generic_file_write, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .fsync = qnx4_sync_file, #endif }; diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index 86f14cacf64..0947fb57dcf 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c @@ -33,8 +33,10 @@ const struct address_space_operations ramfs_aops = { }; const struct file_operations ramfs_file_operations = { - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = simple_sync_file, .sendfile = generic_file_sendfile, diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 677139b48e0..bfe5dbf1002 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -36,8 +36,10 @@ const struct address_space_operations ramfs_aops = { const struct file_operations ramfs_file_operations = { .mmap = ramfs_nommu_mmap, .get_unmapped_area = ramfs_nommu_get_unmapped_area, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .fsync = simple_sync_file, .sendfile = generic_file_sendfile, .llseek = generic_file_llseek, diff --git a/fs/read_write.c b/fs/read_write.c index 32d54cca9bd..4ed839bcb91 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -22,7 +22,8 @@ const struct file_operations generic_ro_fops = { .llseek = generic_file_llseek, - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .mmap = generic_file_readonly_mmap, .sendfile = generic_file_sendfile, }; diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c index dae67048bab..50784d13c87 100644 --- a/fs/smbfs/file.c +++ b/fs/smbfs/file.c @@ -214,13 +214,15 @@ smb_updatepage(struct file *file, struct page *page, unsigned long offset, } static ssize_t -smb_file_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) +smb_file_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { + struct file * file = iocb->ki_filp; struct dentry * dentry = file->f_dentry; ssize_t status; VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), - (unsigned long) count, (unsigned long) *ppos); + (unsigned long) iocb->ki_left, (unsigned long) pos); status = smb_revalidate_inode(dentry); if (status) { @@ -233,7 +235,7 @@ smb_file_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) (long)dentry->d_inode->i_size, dentry->d_inode->i_flags, dentry->d_inode->i_atime); - status = generic_file_read(file, buf, count, ppos); + status = generic_file_aio_read(iocb, iov, nr_segs, pos); out: return status; } @@ -317,14 +319,16 @@ const struct address_space_operations smb_file_aops = { * Write to a file (through the page cache). */ static ssize_t -smb_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +smb_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos) { + struct file * file = iocb->ki_filp; struct dentry * dentry = file->f_dentry; ssize_t result; VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry), - (unsigned long) count, (unsigned long) *ppos); + (unsigned long) iocb->ki_left, (unsigned long) pos); result = smb_revalidate_inode(dentry); if (result) { @@ -337,8 +341,8 @@ smb_file_write(struct file *file, const char __user *buf, size_t count, loff_t * if (result) goto out; - if (count > 0) { - result = generic_file_write(file, buf, count, ppos); + if (iocb->ki_left > 0) { + result = generic_file_aio_write(iocb, iov, nr_segs, pos); VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n", (long) file->f_pos, (long) dentry->d_inode->i_size, dentry->d_inode->i_mtime, dentry->d_inode->i_atime); @@ -402,8 +406,10 @@ smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) const struct file_operations smb_file_operations = { .llseek = remote_llseek, - .read = smb_file_read, - .write = smb_file_write, + .read = do_sync_read, + .aio_read = smb_file_aio_read, + .write = do_sync_write, + .aio_write = smb_file_aio_write, .ioctl = smb_ioctl, .mmap = smb_file_mmap, .open = smb_file_open, diff --git a/fs/sysv/file.c b/fs/sysv/file.c index a59e303135f..47a4b728f15 100644 --- a/fs/sysv/file.c +++ b/fs/sysv/file.c @@ -21,8 +21,10 @@ */ const struct file_operations sysv_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .fsync = sysv_sync_file, .sendfile = generic_file_sendfile, diff --git a/fs/udf/file.c b/fs/udf/file.c index a59e5f33daf..7aedd552cba 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -103,19 +103,21 @@ const struct address_space_operations udf_adinicb_aops = { .commit_write = udf_adinicb_commit_write, }; -static ssize_t udf_file_write(struct file * file, const char __user * buf, - size_t count, loff_t *ppos) +static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t ppos) { ssize_t retval; + struct file *file = iocb->ki_filp; struct inode *inode = file->f_dentry->d_inode; int err, pos; + size_t count = iocb->ki_left; if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) { if (file->f_flags & O_APPEND) pos = inode->i_size; else - pos = *ppos; + pos = ppos; if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + pos + count)) @@ -136,7 +138,7 @@ static ssize_t udf_file_write(struct file * file, const char __user * buf, } } - retval = generic_file_write(file, buf, count, ppos); + retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); if (retval > 0) mark_inode_dirty(inode); @@ -249,11 +251,13 @@ static int udf_release_file(struct inode * inode, struct file * filp) } const struct file_operations udf_file_operations = { - .read = generic_file_read, + .read = do_sync_read, + .aio_read = generic_file_aio_read, .ioctl = udf_ioctl, .open = generic_file_open, .mmap = generic_file_mmap, - .write = udf_file_write, + .write = do_sync_write, + .aio_write = udf_file_aio_write, .release = udf_release_file, .fsync = udf_fsync_file, .sendfile = generic_file_sendfile, diff --git a/fs/ufs/file.c b/fs/ufs/file.c index a9c6e5f04fa..1e096323bad 100644 --- a/fs/ufs/file.c +++ b/fs/ufs/file.c @@ -53,8 +53,10 @@ static int ufs_sync_file(struct file *file, struct dentry *dentry, int datasync) const struct file_operations ufs_file_operations = { .llseek = generic_file_llseek, - .read = generic_file_read, - .write = generic_file_write, + .read = do_sync_read, + .aio_read = generic_file_aio_read, + .write = do_sync_write, + .aio_write = generic_file_aio_write, .mmap = generic_file_mmap, .open = generic_file_open, .fsync = ufs_sync_file, diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 55992b40353..fa842f1c9fa 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c @@ -279,7 +279,9 @@ xfs_read( xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore, (void *)iovp, segs, *offset, ioflags); - ret = __generic_file_aio_read(iocb, iovp, segs, offset); + + iocb->ki_pos = *offset; + ret = generic_file_aio_read(iocb, iovp, segs, *offset); if (ret == -EIOCBQUEUED && !(ioflags & IO_ISAIO)) ret = wait_on_sync_kiocb(iocb); if (ret > 0) -- cgit v1.2.3 From eed4e51fb60c3863c134a5e9f6006b29805ead97 Mon Sep 17 00:00:00 2001 From: Badari Pulavarty Date: Sat, 30 Sep 2006 23:28:49 -0700 Subject: [PATCH] Add vector AIO support This work is initially done by Zach Brown to add support for vectored aio. These are the core changes for AIO to support IOCB_CMD_PREADV/IOCB_CMD_PWRITEV. [akpm@osdl.org: huge build fix] Signed-off-by: Zach Brown Signed-off-by: Christoph Hellwig Signed-off-by: Badari Pulavarty Acked-by: Benjamin LaHaise Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/aio.c | 171 ++++++++++++++++++++++++++++++++++++++------------------ fs/read_write.c | 129 ++++++++++++++++++++++++------------------ 2 files changed, 192 insertions(+), 108 deletions(-) (limited to 'fs') diff --git a/fs/aio.c b/fs/aio.c index 27ff56540c7..2e0d1505ee3 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -415,6 +415,7 @@ static struct kiocb fastcall *__aio_get_req(struct kioctx *ctx) req->ki_retry = NULL; req->ki_dtor = NULL; req->private = NULL; + req->ki_iovec = NULL; INIT_LIST_HEAD(&req->ki_run_list); /* Check if the completion queue has enough free space to @@ -460,6 +461,8 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) if (req->ki_dtor) req->ki_dtor(req); + if (req->ki_iovec != &req->ki_inline_vec) + kfree(req->ki_iovec); kmem_cache_free(kiocb_cachep, req); ctx->reqs_active--; @@ -1301,69 +1304,63 @@ asmlinkage long sys_io_destroy(aio_context_t ctx) return -EINVAL; } -/* - * aio_p{read,write} are the default ki_retry methods for - * IO_CMD_P{READ,WRITE}. They maintains kiocb retry state around potentially - * multiple calls to f_op->aio_read(). They loop around partial progress - * instead of returning -EIOCBRETRY because they don't have the means to call - * kick_iocb(). - */ -static ssize_t aio_pread(struct kiocb *iocb) +static void aio_advance_iovec(struct kiocb *iocb, ssize_t ret) { - struct file *file = iocb->ki_filp; - struct address_space *mapping = file->f_mapping; - struct inode *inode = mapping->host; - ssize_t ret = 0; - - do { - iocb->ki_inline_vec.iov_base = iocb->ki_buf; - iocb->ki_inline_vec.iov_len = iocb->ki_left; - - ret = file->f_op->aio_read(iocb, &iocb->ki_inline_vec, - 1, iocb->ki_pos); - /* - * Can't just depend on iocb->ki_left to determine - * whether we are done. This may have been a short read. - */ - if (ret > 0) { - iocb->ki_buf += ret; - iocb->ki_left -= ret; + struct iovec *iov = &iocb->ki_iovec[iocb->ki_cur_seg]; + + BUG_ON(ret <= 0); + + while (iocb->ki_cur_seg < iocb->ki_nr_segs && ret > 0) { + ssize_t this = min((ssize_t)iov->iov_len, ret); + iov->iov_base += this; + iov->iov_len -= this; + iocb->ki_left -= this; + ret -= this; + if (iov->iov_len == 0) { + iocb->ki_cur_seg++; + iov++; } + } - /* - * For pipes and sockets we return once we have some data; for - * regular files we retry till we complete the entire read or - * find that we can't read any more data (e.g short reads). - */ - } while (ret > 0 && iocb->ki_left > 0 && - !S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode)); - - /* This means we must have transferred all that we could */ - /* No need to retry anymore */ - if ((ret == 0) || (iocb->ki_left == 0)) - ret = iocb->ki_nbytes - iocb->ki_left; - - return ret; + /* the caller should not have done more io than what fit in + * the remaining iovecs */ + BUG_ON(ret > 0 && iocb->ki_left == 0); } -/* see aio_pread() */ -static ssize_t aio_pwrite(struct kiocb *iocb) +static ssize_t aio_rw_vect_retry(struct kiocb *iocb) { struct file *file = iocb->ki_filp; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; + ssize_t (*rw_op)(struct kiocb *, const struct iovec *, + unsigned long, loff_t); ssize_t ret = 0; + unsigned short opcode; + + if ((iocb->ki_opcode == IOCB_CMD_PREADV) || + (iocb->ki_opcode == IOCB_CMD_PREAD)) { + rw_op = file->f_op->aio_read; + opcode = IOCB_CMD_PREADV; + } else { + rw_op = file->f_op->aio_write; + opcode = IOCB_CMD_PWRITEV; + } do { - iocb->ki_inline_vec.iov_base = iocb->ki_buf; - iocb->ki_inline_vec.iov_len = iocb->ki_left; - - ret = file->f_op->aio_write(iocb, &iocb->ki_inline_vec, - 1, iocb->ki_pos); - if (ret > 0) { - iocb->ki_buf += ret; - iocb->ki_left -= ret; - } - } while (ret > 0 && iocb->ki_left > 0); + ret = rw_op(iocb, &iocb->ki_iovec[iocb->ki_cur_seg], + iocb->ki_nr_segs - iocb->ki_cur_seg, + iocb->ki_pos); + if (ret > 0) + aio_advance_iovec(iocb, ret); + + /* retry all partial writes. retry partial reads as long as its a + * regular file. */ + } while (ret > 0 && iocb->ki_left > 0 && + (opcode == IOCB_CMD_PWRITEV || + (!S_ISFIFO(inode->i_mode) && !S_ISSOCK(inode->i_mode)))); + /* This means we must have transferred all that we could */ + /* No need to retry anymore */ if ((ret == 0) || (iocb->ki_left == 0)) ret = iocb->ki_nbytes - iocb->ki_left; @@ -1390,6 +1387,38 @@ static ssize_t aio_fsync(struct kiocb *iocb) return ret; } +static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb) +{ + ssize_t ret; + + ret = rw_copy_check_uvector(type, (struct iovec __user *)kiocb->ki_buf, + kiocb->ki_nbytes, 1, + &kiocb->ki_inline_vec, &kiocb->ki_iovec); + if (ret < 0) + goto out; + + kiocb->ki_nr_segs = kiocb->ki_nbytes; + kiocb->ki_cur_seg = 0; + /* ki_nbytes/left now reflect bytes instead of segs */ + kiocb->ki_nbytes = ret; + kiocb->ki_left = ret; + + ret = 0; +out: + return ret; +} + +static ssize_t aio_setup_single_vector(struct kiocb *kiocb) +{ + kiocb->ki_iovec = &kiocb->ki_inline_vec; + kiocb->ki_iovec->iov_base = kiocb->ki_buf; + kiocb->ki_iovec->iov_len = kiocb->ki_left; + kiocb->ki_nr_segs = 1; + kiocb->ki_cur_seg = 0; + kiocb->ki_nbytes = kiocb->ki_left; + return 0; +} + /* * aio_setup_iocb: * Performs the initial checks and aio retry method @@ -1412,9 +1441,12 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb) ret = security_file_permission(file, MAY_READ); if (unlikely(ret)) break; + ret = aio_setup_single_vector(kiocb); + if (ret) + break; ret = -EINVAL; if (file->f_op->aio_read) - kiocb->ki_retry = aio_pread; + kiocb->ki_retry = aio_rw_vect_retry; break; case IOCB_CMD_PWRITE: ret = -EBADF; @@ -1427,9 +1459,40 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb) ret = security_file_permission(file, MAY_WRITE); if (unlikely(ret)) break; + ret = aio_setup_single_vector(kiocb); + if (ret) + break; + ret = -EINVAL; + if (file->f_op->aio_write) + kiocb->ki_retry = aio_rw_vect_retry; + break; + case IOCB_CMD_PREADV: + ret = -EBADF; + if (unlikely(!(file->f_mode & FMODE_READ))) + break; + ret = security_file_permission(file, MAY_READ); + if (unlikely(ret)) + break; + ret = aio_setup_vectored_rw(READ, kiocb); + if (ret) + break; + ret = -EINVAL; + if (file->f_op->aio_read) + kiocb->ki_retry = aio_rw_vect_retry; + break; + case IOCB_CMD_PWRITEV: + ret = -EBADF; + if (unlikely(!(file->f_mode & FMODE_WRITE))) + break; + ret = security_file_permission(file, MAY_WRITE); + if (unlikely(ret)) + break; + ret = aio_setup_vectored_rw(WRITE, kiocb); + if (ret) + break; ret = -EINVAL; if (file->f_op->aio_write) - kiocb->ki_retry = aio_pwrite; + kiocb->ki_retry = aio_rw_vect_retry; break; case IOCB_CMD_FDSYNC: ret = -EINVAL; diff --git a/fs/read_write.c b/fs/read_write.c index 4ed839bcb91..f792000a28e 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -511,6 +511,74 @@ ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov, /* A write operation does a read from user space and vice versa */ #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) +ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, + unsigned long nr_segs, unsigned long fast_segs, + struct iovec *fast_pointer, + struct iovec **ret_pointer) + { + unsigned long seg; + ssize_t ret; + struct iovec *iov = fast_pointer; + + /* + * SuS says "The readv() function *may* fail if the iovcnt argument + * was less than or equal to 0, or greater than {IOV_MAX}. Linux has + * traditionally returned zero for zero segments, so... + */ + if (nr_segs == 0) { + ret = 0; + goto out; + } + + /* + * First get the "struct iovec" from user memory and + * verify all the pointers + */ + if (nr_segs > UIO_MAXIOV) { + ret = -EINVAL; + goto out; + } + if (nr_segs > fast_segs) { + iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); + if (iov == NULL) { + ret = -ENOMEM; + goto out; + } + } + if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) { + ret = -EFAULT; + goto out; + } + + /* + * According to the Single Unix Specification we should return EINVAL + * if an element length is < 0 when cast to ssize_t or if the + * total length would overflow the ssize_t return value of the + * system call. + */ + ret = 0; + for (seg = 0; seg < nr_segs; seg++) { + void __user *buf = iov[seg].iov_base; + ssize_t len = (ssize_t)iov[seg].iov_len; + + /* see if we we're about to use an invalid len or if + * it's about to overflow ssize_t */ + if (len < 0 || (ret + len < ret)) { + ret = -EINVAL; + goto out; + } + if (unlikely(!access_ok(vrfy_dir(type), buf, len))) { + ret = -EFAULT; + goto out; + } + + ret += len; + } +out: + *ret_pointer = iov; + return ret; +} + static ssize_t do_readv_writev(int type, struct file *file, const struct iovec __user * uvector, unsigned long nr_segs, loff_t *pos) @@ -519,64 +587,20 @@ static ssize_t do_readv_writev(int type, struct file *file, struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; ssize_t ret; - int seg; io_fn_t fn; iov_fn_t fnv; - /* - * SuS says "The readv() function *may* fail if the iovcnt argument - * was less than or equal to 0, or greater than {IOV_MAX}. Linux has - * traditionally returned zero for zero segments, so... - */ - ret = 0; - if (nr_segs == 0) - goto out; - - /* - * First get the "struct iovec" from user memory and - * verify all the pointers - */ - ret = -EINVAL; - if (nr_segs > UIO_MAXIOV) - goto out; - if (!file->f_op) - goto out; - if (nr_segs > UIO_FASTIOV) { - ret = -ENOMEM; - iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL); - if (!iov) - goto out; - } - ret = -EFAULT; - if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) + if (!file->f_op) { + ret = -EINVAL; goto out; + } - /* - * Single unix specification: - * We should -EINVAL if an element length is not >= 0 and fitting an - * ssize_t. The total length is fitting an ssize_t - * - * Be careful here because iov_len is a size_t not an ssize_t - */ - tot_len = 0; - ret = -EINVAL; - for (seg = 0; seg < nr_segs; seg++) { - void __user *buf = iov[seg].iov_base; - ssize_t len = (ssize_t)iov[seg].iov_len; - - if (len < 0) /* size_t not fitting an ssize_t .. */ - goto out; - if (unlikely(!access_ok(vrfy_dir(type), buf, len))) - goto Efault; - tot_len += len; - if ((ssize_t)tot_len < 0) /* maths overflow on the ssize_t */ - goto out; - } - if (tot_len == 0) { - ret = 0; + ret = rw_copy_check_uvector(type, uvector, nr_segs, + ARRAY_SIZE(iovstack), iovstack, &iov); + if (ret <= 0) goto out; - } + tot_len = ret; ret = rw_verify_area(type, file, pos, tot_len); if (ret < 0) goto out; @@ -609,9 +633,6 @@ out: fsnotify_modify(file->f_dentry); } return ret; -Efault: - ret = -EFAULT; - goto out; } ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, -- cgit v1.2.3 From 8f0ab5147951267134612570604cf8341901a80c Mon Sep 17 00:00:00 2001 From: Jay Lan Date: Sat, 30 Sep 2006 23:28:59 -0700 Subject: [PATCH] csa: convert CONFIG tag for extended accounting routines There were a few accounting data/macros that are used in CSA but are #ifdef'ed inside CONFIG_BSD_PROCESS_ACCT. This patch is to change those ifdef's from CONFIG_BSD_PROCESS_ACCT to CONFIG_TASK_XACCT. A few defines are moved from kernel/acct.c and include/linux/acct.h to kernel/tsacct.c and include/linux/tsacct_kern.h. Signed-off-by: Jay Lan Cc: Shailabh Nagar Cc: Balbir Singh Cc: Jes Sorensen Cc: Chris Sturtivant Cc: Tony Ernst Cc: Guillaume Thouvenin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/compat.c | 2 +- fs/exec.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/compat.c b/fs/compat.c index 6b90bf35f61..13fb08d096c 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include /* siocdevprivate_ioctl */ diff --git a/fs/exec.c b/fs/exec.c index a8efe35176b..0db3fc3c5f0 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include -- cgit v1.2.3 From 6902d925d568cd5bfda8a1a328bf08d26d1bab46 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Sat, 30 Sep 2006 23:29:01 -0700 Subject: [PATCH] r/o bind mounts: prepare for write access checks: collapse if() We're shortly going to be adding a bunch more permission checks in these functions. That requires adding either a bunch of new if() conditions, or some gotos. This patch collapses existing if()s and uses gotos instead to prepare for the upcoming changes. Signed-off-by: Dave Hansen Acked-by: Christoph Hellwig Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 93 +++++++++++++++++++++++++++++++++----------------------------- fs/open.c | 64 ++++++++++++++++++++++++------------------ 2 files changed, 87 insertions(+), 70 deletions(-) (limited to 'fs') diff --git a/fs/namei.c b/fs/namei.c index 2892e68d3a8..7bdceedd254 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1934,30 +1934,32 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) { int error = 0; char * tmp; + struct dentry *dentry; + struct nameidata nd; tmp = getname(pathname); error = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - struct dentry *dentry; - struct nameidata nd; + if (IS_ERR(tmp)) + goto out_err; - error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; - dentry = lookup_create(&nd, 1); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - if (!IS_POSIXACL(nd.dentry->d_inode)) - mode &= ~current->fs->umask; - error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); - dput(dentry); - } - mutex_unlock(&nd.dentry->d_inode->i_mutex); - path_release(&nd); -out: - putname(tmp); - } + error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd); + if (error) + goto out; + dentry = lookup_create(&nd, 1); + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto out_unlock; + if (!IS_POSIXACL(nd.dentry->d_inode)) + mode &= ~current->fs->umask; + error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); + dput(dentry); +out_unlock: + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); +out: + putname(tmp); +out_err: return error; } @@ -2056,10 +2058,11 @@ static long do_rmdir(int dfd, const char __user *pathname) mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); dentry = lookup_hash(&nd); error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); - dput(dentry); - } + if (IS_ERR(dentry)) + goto exit2; + error = vfs_rmdir(nd.dentry->d_inode, dentry); + dput(dentry); +exit2: mutex_unlock(&nd.dentry->d_inode->i_mutex); exit1: path_release(&nd); @@ -2199,30 +2202,33 @@ asmlinkage long sys_symlinkat(const char __user *oldname, int error = 0; char * from; char * to; + struct dentry *dentry; + struct nameidata nd; from = getname(oldname); if(IS_ERR(from)) return PTR_ERR(from); to = getname(newname); error = PTR_ERR(to); - if (!IS_ERR(to)) { - struct dentry *dentry; - struct nameidata nd; + if (IS_ERR(to)) + goto out_putname; - error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); - if (error) - goto out; - dentry = lookup_create(&nd, 0); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); - dput(dentry); - } - mutex_unlock(&nd.dentry->d_inode->i_mutex); - path_release(&nd); + error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); + if (error) + goto out; + dentry = lookup_create(&nd, 0); + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto out_unlock; + + error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); + dput(dentry); +out_unlock: + mutex_unlock(&nd.dentry->d_inode->i_mutex); + path_release(&nd); out: - putname(to); - } + putname(to); +out_putname: putname(from); return error; } @@ -2308,10 +2314,11 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, goto out_release; new_dentry = lookup_create(&nd, 0); error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); - dput(new_dentry); - } + if (IS_ERR(new_dentry)) + goto out_unlock; + error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); + dput(new_dentry); +out_unlock: mutex_unlock(&nd.dentry->d_inode->i_mutex); out_release: path_release(&nd); diff --git a/fs/open.c b/fs/open.c index 35c3e454458..89e0c237a63 100644 --- a/fs/open.c +++ b/fs/open.c @@ -386,15 +386,21 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) current->cap_effective = current->cap_permitted; res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); - if (!res) { - res = vfs_permission(&nd, mode); - /* SuS v2 requires we report a read only fs too */ - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) - && !special_file(nd.dentry->d_inode->i_mode)) - res = -EROFS; - path_release(&nd); - } + if (res) + goto out; + + res = vfs_permission(&nd, mode); + /* SuS v2 requires we report a read only fs too */ + if(res || !(mode & S_IWOTH) || + special_file(nd.dentry->d_inode->i_mode)) + goto out_path_release; + + if(IS_RDONLY(nd.dentry->d_inode)) + res = -EROFS; +out_path_release: + path_release(&nd); +out: current->fsuid = old_fsuid; current->fsgid = old_fsgid; current->cap_effective = old_cap; @@ -603,10 +609,11 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) int error; error = user_path_walk(filename, &nd); - if (!error) { - error = chown_common(nd.dentry, user, group); - path_release(&nd); - } + if (error) + goto out; + error = chown_common(nd.dentry, user, group); + path_release(&nd); +out: return error; } @@ -622,10 +629,10 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; error = __user_walk_fd(dfd, filename, follow, &nd); - if (!error) { - error = chown_common(nd.dentry, user, group); - path_release(&nd); - } + if (error) + goto out; + error = chown_common(nd.dentry, user, group); + path_release(&nd); out: return error; } @@ -636,10 +643,11 @@ asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group int error; error = user_path_walk_link(filename, &nd); - if (!error) { - error = chown_common(nd.dentry, user, group); - path_release(&nd); - } + if (error) + goto out; + error = chown_common(nd.dentry, user, group); + path_release(&nd); +out: return error; } @@ -648,15 +656,17 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) { struct file * file; int error = -EBADF; + struct dentry * dentry; file = fget(fd); - if (file) { - struct dentry * dentry; - dentry = file->f_dentry; - audit_inode(NULL, dentry->d_inode); - error = chown_common(dentry, user, group); - fput(file); - } + if (!file) + goto out; + + dentry = file->f_dentry; + audit_inode(NULL, dentry->d_inode); + error = chown_common(dentry, user, group); + fput(file); +out: return error; } -- cgit v1.2.3 From aab520e2f6c80160cabd187a8d0292d1cec8ff68 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Sat, 30 Sep 2006 23:29:02 -0700 Subject: [PATCH] r/o bind mount prepwork: move open_namei()'s vfs_create() The code around vfs_create() in open_namei() is getting a bit too complex. Right now, there is at least the reference count on the dentry, and the i_mutex to worry about. Soon, we'll also have mnt_writecount. So, break the vfs_create() call out of open_namei(), and into a helper function. This duplicates the call to may_open(), but that isn't such a bad thing since the arguments (acc_mode and flag) were being heavily massaged anyway. Signed-off-by: Dave Hansen Acked-by: Christoph Hellwig Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'fs') diff --git a/fs/namei.c b/fs/namei.c index 7bdceedd254..28d49b301d5 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1595,6 +1595,24 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) return 0; } +static int open_namei_create(struct nameidata *nd, struct path *path, + int flag, int mode) +{ + int error; + struct dentry *dir = nd->dentry; + + if (!IS_POSIXACL(dir->d_inode)) + mode &= ~current->fs->umask; + error = vfs_create(dir->d_inode, path->dentry, mode, nd); + mutex_unlock(&dir->d_inode->i_mutex); + dput(nd->dentry); + nd->dentry = path->dentry; + if (error) + return error; + /* Don't check for write permission, don't truncate */ + return may_open(nd, 0, flag & ~O_TRUNC); +} + /* * open_namei() * @@ -1676,18 +1694,10 @@ do_last: /* Negative dentry, just create the file */ if (!path.dentry->d_inode) { - if (!IS_POSIXACL(dir->d_inode)) - mode &= ~current->fs->umask; - error = vfs_create(dir->d_inode, path.dentry, mode, nd); - mutex_unlock(&dir->d_inode->i_mutex); - dput(nd->dentry); - nd->dentry = path.dentry; + error = open_namei_create(nd, &path, flag, mode); if (error) goto exit; - /* Don't check for write permission, don't truncate */ - acc_mode = 0; - flag &= ~O_TRUNC; - goto ok; + return 0; } /* -- cgit v1.2.3 From 9a53c3a783c2fa9b969628e65695c11c3e51e673 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Sat, 30 Sep 2006 23:29:03 -0700 Subject: [PATCH] r/o bind mounts: unlink: monitor i_nlink When a filesystem decrements i_nlink to zero, it means that a write must be performed in order to drop the inode from the filesystem. We're shortly going to have keep filesystems from being remounted r/o between the time that this i_nlink decrement and that write occurs. So, add a little helper function to do the decrements. We'll tie into it in a bit to note when i_nlink hits zero. Signed-off-by: Dave Hansen Acked-by: Christoph Hellwig Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/autofs/root.c | 2 +- fs/autofs4/root.c | 2 +- fs/bfs/dir.c | 9 +++------ fs/cifs/inode.c | 10 +++++----- fs/coda/dir.c | 4 ++-- fs/ext2/namei.c | 2 +- fs/ext3/namei.c | 14 +++++++------- fs/hfs/dir.c | 2 +- fs/hfsplus/dir.c | 2 +- fs/hpfs/namei.c | 6 +++--- fs/jffs/inode-v23.c | 3 +-- fs/jffs2/dir.c | 6 +++--- fs/jfs/namei.c | 14 ++++++-------- fs/libfs.c | 10 +++++----- fs/minix/namei.c | 2 +- fs/msdos/namei.c | 9 ++++----- fs/nfs/dir.c | 6 +++--- fs/ocfs2/namei.c | 4 ++-- fs/qnx4/namei.c | 6 ++---- fs/reiserfs/namei.c | 6 +++--- fs/sysv/namei.c | 2 +- fs/udf/namei.c | 18 ++++++------------ fs/ufs/namei.c | 2 +- fs/vfat/namei.c | 9 ++++----- 24 files changed, 67 insertions(+), 83 deletions(-) (limited to 'fs') diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 9cac08d6a87..54ad7073192 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -414,7 +414,7 @@ static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry) dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL; autofs_hash_delete(ent); - dir->i_nlink--; + drop_nlink(dir); d_drop(dentry); unlock_kernel(); diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 563ef9d7da9..348bec0982b 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -676,7 +676,7 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) dentry->d_inode->i_nlink = 0; if (dir->i_nlink) - dir->i_nlink--; + drop_nlink(dir); return 0; } diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index dcf04cb1328..ce05d1643dd 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -117,8 +117,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode, err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, inode->i_ino); if (err) { - inode->i_nlink--; - mark_inode_dirty(inode); + inode_dec_link_count(inode); iput(inode); unlock_kernel(); return err; @@ -196,9 +195,8 @@ static int bfs_unlink(struct inode * dir, struct dentry * dentry) mark_buffer_dirty(bh); dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(dir); - inode->i_nlink--; inode->i_ctime = dir->i_ctime; - mark_inode_dirty(inode); + inode_dec_link_count(inode); error = 0; out_brelse: @@ -249,9 +247,8 @@ static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry, old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(old_dir); if (new_inode) { - new_inode->i_nlink--; new_inode->i_ctime = CURRENT_TIME_SEC; - mark_inode_dirty(new_inode); + inode_dec_link_count(new_inode); } mark_buffer_dirty(old_bh); error = 0; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 05f874c7441..74441a17e18 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -590,7 +590,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) if (!rc) { if (direntry->d_inode) - direntry->d_inode->i_nlink--; + drop_nlink(direntry->d_inode); } else if (rc == -ENOENT) { d_drop(direntry); } else if (rc == -ETXTBSY) { @@ -609,7 +609,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); if (direntry->d_inode) - direntry->d_inode->i_nlink--; + drop_nlink(direntry->d_inode); } } else if (rc == -EACCES) { /* try only if r/o attribute set in local lookup data? */ @@ -663,7 +663,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { if (direntry->d_inode) - direntry->d_inode->i_nlink--; + drop_nlink(direntry->d_inode); } else if (rc == -ETXTBSY) { int oplock = FALSE; __u16 netfid; @@ -684,7 +684,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); if (direntry->d_inode) - direntry->d_inode->i_nlink--; + drop_nlink(direntry->d_inode); } /* BB if rc = -ETXTBUSY goto the rename logic BB */ } @@ -816,7 +816,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { - inode->i_nlink--; + drop_nlink(inode); i_size_write(direntry->d_inode,0); direntry->d_inode->i_nlink = 0; } diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 8651ea6a23b..0a2fd8bb757 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -367,7 +367,7 @@ int coda_unlink(struct inode *dir, struct dentry *de) } coda_dir_changed(dir, 0); - de->d_inode->i_nlink--; + drop_nlink(de->d_inode); unlock_kernel(); return 0; @@ -394,7 +394,7 @@ int coda_rmdir(struct inode *dir, struct dentry *de) } coda_dir_changed(dir, -1); - de->d_inode->i_nlink--; + drop_nlink(de->d_inode); d_delete(de); unlock_kernel(); diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 4ca82498532..e1af5b4cf80 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -326,7 +326,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, ext2_set_link(new_dir, new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) - new_inode->i_nlink--; + drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { if (dir_de) { diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 235e77b52ea..14c55adfae8 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1621,7 +1621,7 @@ static inline void ext3_inc_count(handle_t *handle, struct inode *inode) static inline void ext3_dec_count(handle_t *handle, struct inode *inode) { - inode->i_nlink--; + drop_nlink(inode); } static int ext3_add_nondir(handle_t *handle, @@ -1743,7 +1743,7 @@ retry: inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; dir_block = ext3_bread (handle, inode, 0, 1, &err); if (!dir_block) { - inode->i_nlink--; /* is this nlink == 0? */ + drop_nlink(inode); /* is this nlink == 0? */ ext3_mark_inode_dirty(handle, inode); iput (inode); goto out_stop; @@ -2053,7 +2053,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry) ext3_orphan_add(handle, inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; ext3_mark_inode_dirty(handle, inode); - dir->i_nlink--; + drop_nlink(dir); ext3_update_dx_flag(dir); ext3_mark_inode_dirty(handle, dir); @@ -2104,7 +2104,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry) dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; ext3_update_dx_flag(dir); ext3_mark_inode_dirty(handle, dir); - inode->i_nlink--; + drop_nlink(inode); if (!inode->i_nlink) ext3_orphan_add(handle, inode); inode->i_ctime = dir->i_ctime; @@ -2326,7 +2326,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, } if (new_inode) { - new_inode->i_nlink--; + drop_nlink(new_inode); new_inode->i_ctime = CURRENT_TIME_SEC; } old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; @@ -2337,9 +2337,9 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino); BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata"); ext3_journal_dirty_metadata(handle, dir_bh); - old_dir->i_nlink--; + drop_nlink(old_dir); if (new_inode) { - new_inode->i_nlink--; + drop_nlink(new_inode); } else { new_dir->i_nlink++; ext3_update_dx_flag(new_dir); diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 7cd8cc03aea..cfef6ad529a 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -246,7 +246,7 @@ static int hfs_unlink(struct inode *dir, struct dentry *dentry) if (res) return res; - inode->i_nlink--; + drop_nlink(inode); hfs_delete_inode(inode); inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 1f9ece0de32..9ceb0dfaa1c 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -338,7 +338,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) return res; if (inode->i_nlink > 0) - inode->i_nlink--; + drop_nlink(inode); hfsplus_delete_inode(inode); if (inode->i_ino != cnid && !inode->i_nlink) { if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 59e7dc182a0..4078b0becc5 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -434,7 +434,7 @@ again: unlock_kernel(); return -ENOSPC; default: - inode->i_nlink--; + drop_nlink(inode); err = 0; } goto out; @@ -494,7 +494,7 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) err = -ENOSPC; break; default: - dir->i_nlink--; + drop_nlink(dir); inode->i_nlink = 0; err = 0; } @@ -636,7 +636,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, hpfs_i(i)->i_parent_dir = new_dir->i_ino; if (S_ISDIR(i->i_mode)) { new_dir->i_nlink++; - old_dir->i_nlink--; + drop_nlink(old_dir); } if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { fnode->up = new_dir->i_ino; diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index 068ef0de8de..3f7899ea4cb 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c @@ -1052,9 +1052,8 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type) dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(dir); - inode->i_nlink--; inode->i_ctime = dir->i_ctime; - mark_inode_dirty(inode); + inode_dec_link_count(inode); d_delete(dentry); /* This also frees the inode */ diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index edd8371fc6a..a5e9f2205b3 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -615,7 +615,7 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry) } ret = jffs2_unlink(dir_i, dentry); if (!ret) - dir_i->i_nlink--; + drop_nlink(dir_i); return ret; } @@ -823,7 +823,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, if (victim_f) { /* There was a victim. Kill it off nicely */ - new_dentry->d_inode->i_nlink--; + drop_nlink(new_dentry->d_inode); /* Don't oops if the victim was a dirent pointing to an inode which didn't exist. */ if (victim_f->inocache) { @@ -862,7 +862,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, } if (S_ISDIR(old_dentry->d_inode->i_mode)) - old_dir_i->i_nlink--; + drop_nlink(old_dir_i); new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 295268ad231..088b85976ac 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -393,9 +393,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) /* update parent directory's link count corresponding * to ".." entry of the target directory deleted */ - dip->i_nlink--; dip->i_ctime = dip->i_mtime = CURRENT_TIME; - mark_inode_dirty(dip); + inode_dec_link_count(dip); /* * OS/2 could have created EA and/or ACL @@ -515,8 +514,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) mark_inode_dirty(dip); /* update target's inode */ - ip->i_nlink--; - mark_inode_dirty(ip); + inode_dec_link_count(ip); /* * commit zero link count object @@ -835,7 +833,7 @@ static int jfs_link(struct dentry *old_dentry, rc = txCommit(tid, 2, &iplist[0], 0); if (rc) { - ip->i_nlink--; + ip->i_nlink--; /* never instantiated */ iput(ip); } else d_instantiate(dentry, ip); @@ -1155,9 +1153,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, old_ip->i_ino, JFS_RENAME); if (rc) goto out4; - new_ip->i_nlink--; + drop_nlink(new_ip); if (S_ISDIR(new_ip->i_mode)) { - new_ip->i_nlink--; + drop_nlink(new_ip); if (new_ip->i_nlink) { mutex_unlock(&JFS_IP(new_ip)->commit_mutex); if (old_dir != new_dir) @@ -1223,7 +1221,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out4; } if (S_ISDIR(old_ip->i_mode)) { - old_dir->i_nlink--; + drop_nlink(old_dir); if (old_dir != new_dir) { /* * Change inode number of parent for moved directory diff --git a/fs/libfs.c b/fs/libfs.c index 3793aaa1457..9204feba75a 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -275,7 +275,7 @@ int simple_unlink(struct inode *dir, struct dentry *dentry) struct inode *inode = dentry->d_inode; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; - inode->i_nlink--; + drop_nlink(inode); dput(dentry); return 0; } @@ -285,9 +285,9 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry) if (!simple_empty(dentry)) return -ENOTEMPTY; - dentry->d_inode->i_nlink--; + drop_nlink(dentry->d_inode); simple_unlink(dir, dentry); - dir->i_nlink--; + drop_nlink(dir); return 0; } @@ -303,9 +303,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_dentry->d_inode) { simple_unlink(new_dir, new_dentry); if (they_are_dirs) - old_dir->i_nlink--; + drop_nlink(old_dir); } else if (they_are_dirs) { - old_dir->i_nlink--; + drop_nlink(old_dir); new_dir->i_nlink++; } diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 5b6a4540a05..299bb66e3bd 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -249,7 +249,7 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry, minix_set_link(new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) - new_inode->i_nlink--; + drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { if (dir_de) { diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index d220165d491..635613f2f65 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -343,7 +343,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; - dir->i_nlink--; + drop_nlink(dir); inode->i_nlink = 0; inode->i_ctime = CURRENT_TIME_SEC; @@ -549,7 +549,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, if (err) goto error_dotdot; } - old_dir->i_nlink--; + drop_nlink(old_dir); if (!new_inode) new_dir->i_nlink++; } @@ -566,10 +566,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, mark_inode_dirty(old_dir); if (new_inode) { + drop_nlink(new_inode); if (is_dir) - new_inode->i_nlink -= 2; - else - new_inode->i_nlink--; + drop_nlink(new_inode); new_inode->i_ctime = ts; } out: diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 7432f1a43f3..26eecb86f9b 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -843,7 +843,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) nfs_inode_return_delegation(inode); if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { lock_kernel(); - inode->i_nlink--; + drop_nlink(inode); nfs_complete_unlink(dentry); unlock_kernel(); } @@ -1401,7 +1401,7 @@ static int nfs_safe_remove(struct dentry *dentry) error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); /* The VFS may want to delete this inode */ if (error == 0) - inode->i_nlink--; + drop_nlink(inode); nfs_mark_for_revalidate(inode); nfs_end_data_update(inode); } else @@ -1639,7 +1639,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out; } } else - new_inode->i_nlink--; + drop_nlink(new_inode); go_ahead: /* diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 849c3b4bb94..40f83f53053 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -739,7 +739,7 @@ static int ocfs2_link(struct dentry *old_dentry, err = ocfs2_journal_dirty(handle, fe_bh); if (err < 0) { le16_add_cpu(&fe->i_links_count, -1); - inode->i_nlink--; + drop_nlink(inode); mlog_errno(err); goto bail; } @@ -749,7 +749,7 @@ static int ocfs2_link(struct dentry *old_dentry, parent_fe_bh, de_bh); if (err) { le16_add_cpu(&fe->i_links_count, -1); - inode->i_nlink--; + drop_nlink(inode); mlog_errno(err); goto bail; } diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c index c3d83f67154..ad5afa4ea8f 100644 --- a/fs/qnx4/namei.c +++ b/fs/qnx4/namei.c @@ -189,8 +189,7 @@ int qnx4_rmdir(struct inode *dir, struct dentry *dentry) inode->i_nlink = 0; mark_inode_dirty(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; - dir->i_nlink--; - mark_inode_dirty(dir); + inode_dec_link_count(dir); retval = 0; end_rmdir: @@ -234,9 +233,8 @@ int qnx4_unlink(struct inode *dir, struct dentry *dentry) mark_buffer_dirty(bh); dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; mark_inode_dirty(dir); - inode->i_nlink--; inode->i_ctime = dir->i_ctime; - mark_inode_dirty(inode); + inode_dec_link_count(inode); retval = 0; end_unlink: diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index c61710e49c6..c76d427e027 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -20,7 +20,7 @@ #include #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } -#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--; +#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i); // directory item contains array of entry headers. This performs // binary search through that array @@ -994,7 +994,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) inode->i_nlink = 1; } - inode->i_nlink--; + drop_nlink(inode); /* * we schedule before doing the add_save_link call, save the link @@ -1475,7 +1475,7 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (S_ISDIR(new_dentry_inode->i_mode)) { new_dentry_inode->i_nlink = 0; } else { - new_dentry_inode->i_nlink--; + drop_nlink(new_dentry_inode); } new_dentry_inode->i_ctime = ctime; savelink = new_dentry_inode->i_nlink; diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index b8a73f716fb..f7c08db8e34 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -250,7 +250,7 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry, sysv_set_link(new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) - new_inode->i_nlink--; + drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { if (dir_de) { diff --git a/fs/udf/namei.c b/fs/udf/namei.c index ab9a7629d23..d14d25534aa 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -878,8 +878,7 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry) inode->i_nlink); inode->i_nlink = 0; inode->i_size = 0; - mark_inode_dirty(inode); - dir->i_nlink --; + inode_dec_link_count(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); mark_inode_dirty(dir); @@ -923,8 +922,7 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry) goto end_unlink; dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); mark_inode_dirty(dir); - inode->i_nlink--; - mark_inode_dirty(inode); + inode_dec_link_count(inode); inode->i_ctime = dir->i_ctime; retval = 0; @@ -1101,8 +1099,7 @@ out: return err; out_no_entry: - inode->i_nlink--; - mark_inode_dirty(inode); + inode_dec_link_count(inode); iput(inode); goto out; } @@ -1261,9 +1258,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, if (new_inode) { - new_inode->i_nlink--; new_inode->i_ctime = current_fs_time(new_inode->i_sb); - mark_inode_dirty(new_inode); + inode_dec_link_count(new_inode); } old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb); mark_inode_dirty(old_dir); @@ -1279,12 +1275,10 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, } else mark_buffer_dirty_inode(dir_bh, old_inode); - old_dir->i_nlink --; - mark_inode_dirty(old_dir); + inode_dec_link_count(old_dir); if (new_inode) { - new_inode->i_nlink --; - mark_inode_dirty(new_inode); + inode_dec_link_count(new_inode); } else { diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index d344b411e26..e84c0ecf073 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -308,7 +308,7 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, ufs_set_link(new_dir, new_de, new_page, old_inode); new_inode->i_ctime = CURRENT_TIME_SEC; if (dir_de) - new_inode->i_nlink--; + drop_nlink(new_inode); inode_dec_link_count(new_inode); } else { if (dir_de) { diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 9a8f48bae95..090d74ffa06 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -782,7 +782,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; - dir->i_nlink--; + drop_nlink(dir); inode->i_nlink = 0; inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; @@ -930,7 +930,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, if (err) goto error_dotdot; } - old_dir->i_nlink--; + drop_nlink(old_dir); if (!new_inode) new_dir->i_nlink++; } @@ -947,10 +947,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, mark_inode_dirty(old_dir); if (new_inode) { + drop_nlink(new_inode); if (is_dir) - new_inode->i_nlink -= 2; - else - new_inode->i_nlink--; + drop_nlink(new_inode); new_inode->i_ctime = ts; } out: -- cgit v1.2.3 From d8c76e6f45c111c32a4b3e50a2adc9210737b0d8 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Sat, 30 Sep 2006 23:29:04 -0700 Subject: [PATCH] r/o bind mount prepwork: inc_nlink() helper This is mostly included for parity with dec_nlink(), where we will have some more hooks. This one should stay pretty darn straightforward for now. Signed-off-by: Dave Hansen Acked-by: Christoph Hellwig Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/9p/vfs_inode.c | 2 +- fs/autofs/root.c | 2 +- fs/autofs4/root.c | 2 +- fs/bfs/dir.c | 2 +- fs/cifs/inode.c | 2 +- fs/coda/dir.c | 2 +- fs/configfs/dir.c | 4 ++-- fs/configfs/mount.c | 2 +- fs/debugfs/inode.c | 4 ++-- fs/ext3/namei.c | 6 +++--- fs/fuse/control.c | 2 +- fs/hfsplus/dir.c | 2 +- fs/hpfs/namei.c | 4 ++-- fs/hugetlbfs/inode.c | 4 ++-- fs/jffs2/dir.c | 6 +++--- fs/jffs2/fs.c | 6 +++--- fs/jfs/namei.c | 6 +++--- fs/libfs.c | 4 ++-- fs/msdos/namei.c | 4 ++-- fs/ocfs2/dlm/dlmfs.c | 6 +++--- fs/ocfs2/namei.c | 8 ++++---- fs/ramfs/inode.c | 4 ++-- fs/reiserfs/namei.c | 6 +++--- fs/sysfs/dir.c | 4 ++-- fs/sysfs/mount.c | 2 +- fs/udf/inode.c | 2 +- fs/udf/namei.c | 6 +++--- fs/vfat/namei.c | 4 ++-- 28 files changed, 54 insertions(+), 54 deletions(-) (limited to 'fs') diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 7a7ec2d1d2f..5241c600ce2 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -233,7 +233,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) inode->i_op = &v9fs_symlink_inode_operations; break; case S_IFDIR: - inode->i_nlink++; + inc_nlink(inode); if(v9ses->extended) inode->i_op = &v9fs_dir_inode_operations_ext; else diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 54ad7073192..368a1c33a3c 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -466,7 +466,7 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) ent->dentry = dentry; autofs_hash_insert(dh,ent); - dir->i_nlink++; + inc_nlink(dir); d_instantiate(dentry, iget(dir->i_sb,ino)); unlock_kernel(); diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 348bec0982b..e21bb466820 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -713,7 +713,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (p_ino && dentry->d_parent != dentry) atomic_inc(&p_ino->count); ino->inode = inode; - dir->i_nlink++; + inc_nlink(dir); dir->i_mtime = CURRENT_TIME; return 0; diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index ce05d1643dd..a650f1d0b85 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -163,7 +163,7 @@ static int bfs_link(struct dentry * old, struct inode * dir, struct dentry * new unlock_kernel(); return err; } - inode->i_nlink++; + inc_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); atomic_inc(&inode->i_count); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 74441a17e18..76b7fb34101 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -735,7 +735,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) cFYI(1, ("cifs_mkdir returned 0x%x", rc)); d_drop(direntry); } else { - inode->i_nlink++; + inc_nlink(inode); if (pTcon->ses->capabilities & CAP_UNIX) rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,xid); diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 0a2fd8bb757..0102b28a15f 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -304,7 +304,7 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode, coda_dir_changed(dir_inode, 0); atomic_inc(&inode->i_count); d_instantiate(de, inode); - inode->i_nlink++; + inc_nlink(inode); out: unlock_kernel(); diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 816e8ef6456..8a3b6a1a6ad 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -139,7 +139,7 @@ static int init_dir(struct inode * inode) inode->i_fop = &configfs_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); return 0; } @@ -169,7 +169,7 @@ static int create_dir(struct config_item * k, struct dentry * p, if (!error) { error = configfs_create(d, mode, init_dir); if (!error) { - p->d_inode->i_nlink++; + inc_nlink(p->d_inode); (d)->d_op = &configfs_dentry_ops; } else { struct configfs_dirent *sd = d->d_fsdata; diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index 3e5fe843e1d..68bd5c93ca5 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c @@ -84,7 +84,7 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent) inode->i_op = &configfs_dir_inode_operations; inode->i_fop = &configfs_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); } else { pr_debug("configfs: could not get root inode\n"); return -ENOMEM; diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 269e649e6dc..ecf3da9edf2 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -54,7 +54,7 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); break; } } @@ -87,7 +87,7 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; res = debugfs_mknod(dir, dentry, mode, 0); if (!res) - dir->i_nlink++; + inc_nlink(dir); return res; } diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 14c55adfae8..b45c88bd5f7 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1616,7 +1616,7 @@ static int ext3_delete_entry (handle_t *handle, */ static inline void ext3_inc_count(handle_t *handle, struct inode *inode) { - inode->i_nlink++; + inc_nlink(inode); } static inline void ext3_dec_count(handle_t *handle, struct inode *inode) @@ -1775,7 +1775,7 @@ retry: iput (inode); goto out_stop; } - dir->i_nlink++; + inc_nlink(dir); ext3_update_dx_flag(dir); ext3_mark_inode_dirty(handle, dir); d_instantiate(dentry, inode); @@ -2341,7 +2341,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, if (new_inode) { drop_nlink(new_inode); } else { - new_dir->i_nlink++; + inc_nlink(new_dir); ext3_update_dx_flag(new_dir); ext3_mark_inode_dirty(handle, new_dir); } diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 79ec1f23d4d..16b39c053d4 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -116,7 +116,7 @@ int fuse_ctl_add_conn(struct fuse_conn *fc) return 0; parent = fuse_control_sb->s_root; - parent->d_inode->i_nlink++; + inc_nlink(parent->d_inode); sprintf(name, "%llu", (unsigned long long) fc->id); parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 2, &simple_dir_inode_operations, diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 9ceb0dfaa1c..99b4ed1b87d 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -298,7 +298,7 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, if (res) return res; - inode->i_nlink++; + inc_nlink(inode); hfsplus_instantiate(dst_dentry, inode, cnid); atomic_inc(&inode->i_count); inode->i_ctime = CURRENT_TIME_SEC; diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 4078b0becc5..25dd6f81eca 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -89,7 +89,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) brelse(bh); hpfs_mark_4buffers_dirty(&qbh0); hpfs_brelse4(&qbh0); - dir->i_nlink++; + inc_nlink(dir); insert_inode_hash(result); if (result->i_uid != current->fsuid || @@ -635,7 +635,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, end: hpfs_i(i)->i_parent_dir = new_dir->i_ino; if (S_ISDIR(i->i_mode)) { - new_dir->i_nlink++; + inc_nlink(new_dir); drop_nlink(old_dir); } if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index f5b8f329aca..5e03b2f67b9 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -377,7 +377,7 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid, inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; @@ -418,7 +418,7 @@ static int hugetlbfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { int retval = hugetlbfs_mknod(dir, dentry, mode | S_IFDIR, 0); if (!retval) - dir->i_nlink++; + inc_nlink(dir); return retval; } diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index a5e9f2205b3..9def6adf4a5 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -588,7 +588,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode) } dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime)); - dir_i->i_nlink++; + inc_nlink(dir_i); jffs2_free_raw_dirent(rd); @@ -836,7 +836,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, /* If it was a directory we moved, and there was no victim, increase i_nlink on its new parent */ if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f) - new_dir_i->i_nlink++; + inc_nlink(new_dir_i); /* Unlink the original */ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), @@ -848,7 +848,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, /* Oh shit. We really ought to make a single node which can do both atomically */ struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode); down(&f->sem); - old_dentry->d_inode->i_nlink++; + inc_nlink(old_dentry->d_inode); if (f->inocache) f->inocache->nlink++; up(&f->sem); diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 72d9909d95f..7bc1a4201c0 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -277,13 +277,13 @@ void jffs2_read_inode (struct inode *inode) for (fd=f->dents; fd; fd = fd->next) { if (fd->type == DT_DIR && fd->ino) - inode->i_nlink++; + inc_nlink(inode); } /* and '..' */ - inode->i_nlink++; + inc_nlink(inode); /* Root dir gets i_nlink 3 for some reason */ if (inode->i_ino == 1) - inode->i_nlink++; + inc_nlink(inode); inode->i_op = &jffs2_dir_inode_operations; inode->i_fop = &jffs2_dir_operations; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 088b85976ac..8cef88170aa 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -292,7 +292,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) mark_inode_dirty(ip); /* update parent directory inode */ - dip->i_nlink++; /* for '..' from child directory */ + inc_nlink(dip); /* for '..' from child directory */ dip->i_ctime = dip->i_mtime = CURRENT_TIME; mark_inode_dirty(dip); @@ -822,7 +822,7 @@ static int jfs_link(struct dentry *old_dentry, goto free_dname; /* update object inode */ - ip->i_nlink++; /* for new link */ + inc_nlink(ip); /* for new link */ ip->i_ctime = CURRENT_TIME; dir->i_ctime = dir->i_mtime = CURRENT_TIME; mark_inode_dirty(dir); @@ -1206,7 +1206,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, goto out4; } if (S_ISDIR(old_ip->i_mode)) - new_dir->i_nlink++; + inc_nlink(new_dir); } /* * Remove old directory entry diff --git a/fs/libfs.c b/fs/libfs.c index 9204feba75a..bd08e0e64a8 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -243,7 +243,7 @@ int simple_link(struct dentry *old_dentry, struct inode *dir, struct dentry *den struct inode *inode = old_dentry->d_inode; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; - inode->i_nlink++; + inc_nlink(inode); atomic_inc(&inode->i_count); dget(dentry); d_instantiate(dentry, inode); @@ -306,7 +306,7 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, drop_nlink(old_dir); } else if (they_are_dirs) { drop_nlink(old_dir); - new_dir->i_nlink++; + inc_nlink(new_dir); } old_dir->i_ctime = old_dir->i_mtime = new_dir->i_ctime = diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index 635613f2f65..fa868c75590 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -389,7 +389,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, int mode) err = msdos_add_entry(dir, msdos_name, 1, is_hid, cluster, &ts, &sinfo); if (err) goto out_free; - dir->i_nlink++; + inc_nlink(dir); inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); brelse(sinfo.bh); @@ -551,7 +551,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, } drop_nlink(old_dir); if (!new_inode) - new_dir->i_nlink++; + inc_nlink(new_dir); } err = fat_remove_entries(old_dir, &old_sinfo); /* and releases bh */ diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index 0368c640218..16b8d1ba706 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c @@ -338,7 +338,7 @@ static struct inode *dlmfs_get_root_inode(struct super_block *sb) inode->i_blocks = 0; inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_nlink++; + inc_nlink(inode); inode->i_fop = &simple_dir_operations; inode->i_op = &dlmfs_root_inode_operations; @@ -395,7 +395,7 @@ static struct inode *dlmfs_get_inode(struct inode *parent, /* directory inodes start off with i_nlink == * 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); break; } @@ -449,7 +449,7 @@ static int dlmfs_mkdir(struct inode * dir, } ip->ip_dlm = dlm; - dir->i_nlink++; + inc_nlink(dir); d_instantiate(dentry, inode); dget(dentry); /* Extra count - pin the dentry in core */ diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 40f83f53053..8c370a39e0c 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -429,7 +429,7 @@ static int ocfs2_mknod(struct inode *dir, mlog_errno(status); goto leave; } - dir->i_nlink++; + inc_nlink(dir); } status = ocfs2_add_entry(handle, dentry, inode, @@ -730,7 +730,7 @@ static int ocfs2_link(struct dentry *old_dentry, goto bail; } - inode->i_nlink++; + inc_nlink(inode); inode->i_ctime = CURRENT_TIME; fe->i_links_count = cpu_to_le16(inode->i_nlink); fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); @@ -952,7 +952,7 @@ static int ocfs2_unlink(struct inode *dir, parent_node_bh); if (status < 0) { mlog_errno(status); - dir->i_nlink++; + inc_nlink(dir); } } @@ -1382,7 +1382,7 @@ static int ocfs2_rename(struct inode *old_dir, if (new_inode) { new_inode->i_nlink--; } else { - new_dir->i_nlink++; + inc_nlink(new_dir); mark_inode_dirty(new_dir); } } diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index bc0e5166242..2faf4cdf61b 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -75,7 +75,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); break; case S_IFLNK: inode->i_op = &page_symlink_inode_operations; @@ -113,7 +113,7 @@ static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) { int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0); if (!retval) - dir->i_nlink++; + inc_nlink(dir); return retval; } diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index c76d427e027..cf92e89515f 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -19,7 +19,7 @@ #include #include -#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } +#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; } #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i); // directory item contains array of entry headers. This performs @@ -1006,7 +1006,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) reiserfs_cut_from_item(&th, &path, &(de.de_entry_key), dir, NULL, 0); if (retval < 0) { - inode->i_nlink++; + inc_nlink(inode); goto end_unlink; } inode->i_ctime = CURRENT_TIME_SEC; @@ -1143,7 +1143,7 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir, } /* inc before scheduling so reiserfs_unlink knows we are here */ - inode->i_nlink++; + inc_nlink(inode); retval = journal_begin(&th, dir->i_sb, jbegin_count); if (retval) { diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 5f3d725d112..3aa3434621c 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -103,7 +103,7 @@ static int init_dir(struct inode * inode) inode->i_fop = &sysfs_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); return 0; } @@ -137,7 +137,7 @@ static int create_dir(struct kobject * k, struct dentry * p, if (!error) { error = sysfs_create(*d, mode, init_dir); if (!error) { - p->d_inode->i_nlink++; + inc_nlink(p->d_inode); (*d)->d_op = &sysfs_dentry_ops; d_rehash(*d); } diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 40190c48927..20551a1b8a5 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c @@ -49,7 +49,7 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent) inode->i_op = &sysfs_dir_inode_operations; inode->i_fop = &sysfs_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ - inode->i_nlink++; + inc_nlink(inode); } else { pr_debug("sysfs: could not get root inode\n"); return -ENOMEM; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index b223b32db99..ae21a0e59e9 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -1165,7 +1165,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) inode->i_op = &udf_dir_inode_operations; inode->i_fop = &udf_dir_operations; inode->i_mode |= S_IFDIR; - inode->i_nlink ++; + inc_nlink(inode); break; } case ICBTAG_FILE_TYPE_REALTIME: diff --git a/fs/udf/namei.c b/fs/udf/namei.c index d14d25534aa..e40c95e6511 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -762,7 +762,7 @@ static int udf_mkdir(struct inode * dir, struct dentry * dentry, int mode) cpu_to_le32(UDF_I_UNIQUE(inode) & 0x00000000FFFFFFFFUL); cfi.fileCharacteristics |= FID_FILE_CHAR_DIRECTORY; udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); - dir->i_nlink++; + inc_nlink(dir); mark_inode_dirty(dir); d_instantiate(dentry, inode); if (fibh.sbh != fibh.ebh) @@ -1147,7 +1147,7 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir, if (fibh.sbh != fibh.ebh) udf_release_data(fibh.ebh); udf_release_data(fibh.sbh); - inode->i_nlink ++; + inc_nlink(inode); inode->i_ctime = current_fs_time(inode->i_sb); mark_inode_dirty(inode); atomic_inc(&inode->i_count); @@ -1282,7 +1282,7 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry, } else { - new_dir->i_nlink ++; + inc_nlink(new_dir); mark_inode_dirty(new_dir); } } diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 090d74ffa06..5846ba2d5d9 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -837,7 +837,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (err) goto out_free; dir->i_version++; - dir->i_nlink++; + inc_nlink(dir); inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); brelse(sinfo.bh); @@ -932,7 +932,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, } drop_nlink(old_dir); if (!new_inode) - new_dir->i_nlink++; + inc_nlink(new_dir); } err = fat_remove_entries(old_dir, &old_sinfo); /* and releases bh */ -- cgit v1.2.3 From 17ff785691503f63ec648df82a7fdaece7695561 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Sat, 30 Sep 2006 23:29:05 -0700 Subject: [PATCH] r/o bind mounts: clean up OCFS2 nlink handling OCFS2 does some operations on i_nlink, then reverts them if some of its operations fail to complete. This does not fit in well with the drop_nlink() logic where we expect i_nlink to stay at zero once it gets there. So, delay all of the nlink operations until we're sure that the operations have completed. Also, introduce a small helper to check whether an inode has proper "unlinkable" i_nlink counts no matter whether it is a directory or regular inode. This patch is broken out from the others because it does contain some logical changes. Signed-off-by: Dave Hansen Signed-off-by: Mark Fasheh Cc: Christoph Hellwig Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ocfs2/namei.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'fs') diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 8c370a39e0c..259155f0eb2 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -795,11 +795,23 @@ static int ocfs2_remote_dentry_delete(struct dentry *dentry) return ret; } +static inline int inode_is_unlinkable(struct inode *inode) +{ + if (S_ISDIR(inode->i_mode)) { + if (inode->i_nlink == 2) + return 1; + return 0; + } + + if (inode->i_nlink == 1) + return 1; + return 0; +} + static int ocfs2_unlink(struct inode *dir, struct dentry *dentry) { int status; - unsigned int saved_nlink = 0; struct inode *inode = dentry->d_inode; struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); u64 blkno; @@ -874,16 +886,6 @@ static int ocfs2_unlink(struct inode *dir, } } - /* There are still a few steps left until we can consider the - * unlink to have succeeded. Save off nlink here before - * modification so we can set it back in case we hit an issue - * before commit. */ - saved_nlink = inode->i_nlink; - if (S_ISDIR(inode->i_mode)) - inode->i_nlink = 0; - else - inode->i_nlink--; - status = ocfs2_remote_dentry_delete(dentry); if (status < 0) { /* This vote should succeed under all normal @@ -892,7 +894,7 @@ static int ocfs2_unlink(struct inode *dir, goto leave; } - if (!inode->i_nlink) { + if (inode_is_unlinkable(inode)) { status = ocfs2_prepare_orphan_dir(osb, handle, inode, orphan_name, &orphan_entry_bh); @@ -919,7 +921,7 @@ static int ocfs2_unlink(struct inode *dir, fe = (struct ocfs2_dinode *) fe_bh->b_data; - if (!inode->i_nlink) { + if (inode_is_unlinkable(inode)) { status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, orphan_entry_bh); if (status < 0) { @@ -935,10 +937,10 @@ static int ocfs2_unlink(struct inode *dir, goto leave; } - /* We can set nlink on the dinode now. clear the saved version - * so that it doesn't get set later. */ + if (S_ISDIR(inode->i_mode)) + drop_nlink(inode); + drop_nlink(inode); fe->i_links_count = cpu_to_le16(inode->i_nlink); - saved_nlink = 0; status = ocfs2_journal_dirty(handle, fe_bh); if (status < 0) { @@ -947,7 +949,7 @@ static int ocfs2_unlink(struct inode *dir, } if (S_ISDIR(inode->i_mode)) { - dir->i_nlink--; + drop_nlink(dir); status = ocfs2_mark_inode_dirty(handle, dir, parent_node_bh); if (status < 0) { @@ -957,9 +959,6 @@ static int ocfs2_unlink(struct inode *dir, } leave: - if (status < 0 && saved_nlink) - inode->i_nlink = saved_nlink; - if (handle) ocfs2_commit_trans(handle); -- cgit v1.2.3 From ce71ec36840368b877fb63bd14c8e67ab62d08b1 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Sat, 30 Sep 2006 23:29:06 -0700 Subject: [PATCH] r/o bind mounts: monitor zeroing of i_nlink Some filesystems, instead of simply decrementing i_nlink, simply zero it during an unlink operation. We need to catch these in addition to the decrement operations. Signed-off-by: Dave Hansen Acked-by: Christoph Hellwig Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/autofs4/root.c | 4 ++-- fs/cifs/inode.c | 2 +- fs/ext3/namei.c | 2 +- fs/fuse/dir.c | 4 ++-- fs/hfs/dir.c | 2 +- fs/hfsplus/dir.c | 4 ++-- fs/hpfs/namei.c | 4 ++-- fs/jfs/namei.c | 2 +- fs/msdos/namei.c | 4 ++-- fs/nfs/dir.c | 2 +- fs/qnx4/namei.c | 2 +- fs/reiserfs/namei.c | 4 ++-- fs/udf/namei.c | 2 +- fs/vfat/namei.c | 4 ++-- 14 files changed, 21 insertions(+), 21 deletions(-) (limited to 'fs') diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index e21bb466820..c1493524da4 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -638,7 +638,7 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry) dput(ino->dentry); dentry->d_inode->i_size = 0; - dentry->d_inode->i_nlink = 0; + clear_nlink(dentry->d_inode); dir->i_mtime = CURRENT_TIME; @@ -673,7 +673,7 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry) } dput(ino->dentry); dentry->d_inode->i_size = 0; - dentry->d_inode->i_nlink = 0; + clear_nlink(dentry->d_inode); if (dir->i_nlink) drop_nlink(dir); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 76b7fb34101..6b90ef98e4c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -818,7 +818,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) if (!rc) { drop_nlink(inode); i_size_write(direntry->d_inode,0); - direntry->d_inode->i_nlink = 0; + clear_nlink(direntry->d_inode); } cifsInode = CIFS_I(direntry->d_inode); diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index b45c88bd5f7..906731a20f1 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -2045,7 +2045,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry) "empty directory has nlink!=2 (%d)", inode->i_nlink); inode->i_version++; - inode->i_nlink = 0; + clear_nlink(inode); /* There's no need to set i_disksize: the fact that i_nlink is * zero will ensure that the right thing happens during any * recovery. */ diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index f85b2a282f1..8605155db17 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -508,7 +508,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) /* Set nlink to zero so the inode can be cleared, if the inode does have more links this will be discovered at the next lookup/getattr */ - inode->i_nlink = 0; + clear_nlink(inode); fuse_invalidate_attr(inode); fuse_invalidate_attr(dir); fuse_invalidate_entry_cache(entry); @@ -534,7 +534,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) err = req->out.h.error; fuse_put_request(fc, req); if (!err) { - entry->d_inode->i_nlink = 0; + clear_nlink(entry->d_inode); fuse_invalidate_attr(dir); fuse_invalidate_entry_cache(entry); } else if (err == -EINTR) diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index cfef6ad529a..37d681b4f21 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -273,7 +273,7 @@ static int hfs_rmdir(struct inode *dir, struct dentry *dentry) res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); if (res) return res; - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; hfs_delete_inode(inode); mark_inode_dirty(inode); diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 99b4ed1b87d..7e309751645 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -348,7 +348,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) } else inode->i_flags |= S_DEAD; } else - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); @@ -387,7 +387,7 @@ static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry) res = hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name); if (res) return res; - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; hfsplus_delete_inode(inode); mark_inode_dirty(inode); diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 25dd6f81eca..2507e7393f3 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -495,7 +495,7 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) break; default: drop_nlink(dir); - inode->i_nlink = 0; + clear_nlink(inode); err = 0; } goto out; @@ -590,7 +590,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, int r; if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) { if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, (char *)new_name, new_len, NULL, &qbh1))) { - new_inode->i_nlink = 0; + clear_nlink(new_inode); copy_de(nde, &de); memcpy(nde->name, new_name, new_len); hpfs_mark_4buffers_dirty(&qbh1); diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 8cef88170aa..b8d16a6aa88 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -414,7 +414,7 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) JFS_IP(ip)->acl.flag = 0; /* mark the target directory as deleted */ - ip->i_nlink = 0; + clear_nlink(ip); mark_inode_dirty(ip); rc = txCommit(tid, 2, &iplist[0], 0); diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index fa868c75590..b0f01b3b053 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c @@ -345,7 +345,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) goto out; drop_nlink(dir); - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; fat_detach(inode); out: @@ -430,7 +430,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry) err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; fat_detach(inode); out: diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 26eecb86f9b..481f8892a91 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1286,7 +1286,7 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry) error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); /* Ensure the VFS deletes this inode */ if (error == 0 && dentry->d_inode != NULL) - dentry->d_inode->i_nlink = 0; + clear_nlink(dentry->d_inode); nfs_end_data_update(dir); unlock_kernel(); diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c index ad5afa4ea8f..733cdf01d64 100644 --- a/fs/qnx4/namei.c +++ b/fs/qnx4/namei.c @@ -186,7 +186,7 @@ int qnx4_rmdir(struct inode *dir, struct dentry *dentry) memset(de->di_fname, 0, sizeof de->di_fname); de->di_mode = 0; mark_buffer_dirty(bh); - inode->i_nlink = 0; + clear_nlink(inode); mark_inode_dirty(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; inode_dec_link_count(dir); diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index cf92e89515f..16e9cff8f15 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -913,7 +913,7 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) reiserfs_warning(inode->i_sb, "%s: empty directory has nlink " "!= 2 (%d)", __FUNCTION__, inode->i_nlink); - inode->i_nlink = 0; + clear_nlink(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; reiserfs_update_sd(&th, inode); @@ -1473,7 +1473,7 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (new_dentry_inode) { // adjust link number of the victim if (S_ISDIR(new_dentry_inode->i_mode)) { - new_dentry_inode->i_nlink = 0; + clear_nlink(new_dentry_inode); } else { drop_nlink(new_dentry_inode); } diff --git a/fs/udf/namei.c b/fs/udf/namei.c index e40c95e6511..73163325e5e 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -876,7 +876,7 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry) udf_warning(inode->i_sb, "udf_rmdir", "empty directory has nlink != 2 (%d)", inode->i_nlink); - inode->i_nlink = 0; + clear_nlink(inode); inode->i_size = 0; inode_dec_link_count(inode); inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index 5846ba2d5d9..edb711ff7b0 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c @@ -784,7 +784,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) goto out; drop_nlink(dir); - inode->i_nlink = 0; + clear_nlink(inode); inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; fat_detach(inode); out: @@ -808,7 +808,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry) err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; - inode->i_nlink = 0; + clear_nlink(inode); inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; fat_detach(inode); out: -- cgit v1.2.3 From d6cbd281d189977b38eac7eb2a4678de19b6b483 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 30 Sep 2006 23:29:26 -0700 Subject: [PATCH] Some cleanup in the pipe code Split the big and hard to read do_pipe function into smaller pieces. This creates new create_write_pipe/free_write_pipe/create_read_pipe functions. These functions are made global so that they can be used by other parts of the kernel. The resulting code is more generic and easier to read and has cleaner error handling and less gotos. [akpm@osdl.org: cleanup] Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/pipe.c | 155 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 93 insertions(+), 62 deletions(-) (limited to 'fs') diff --git a/fs/pipe.c b/fs/pipe.c index 2e60e1c8815..b1626f269a3 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -874,87 +874,118 @@ fail_inode: return NULL; } -int do_pipe(int *fd) +struct file *create_write_pipe(void) { - struct qstr this; - char name[32]; + int err; + struct inode *inode; + struct file *f; struct dentry *dentry; - struct inode * inode; - struct file *f1, *f2; - int error; - int i, j; - - error = -ENFILE; - f1 = get_empty_filp(); - if (!f1) - goto no_files; - - f2 = get_empty_filp(); - if (!f2) - goto close_f1; + char name[32]; + struct qstr this; + f = get_empty_filp(); + if (!f) + return ERR_PTR(-ENFILE); + err = -ENFILE; inode = get_pipe_inode(); if (!inode) - goto close_f12; + goto err_file; - error = get_unused_fd(); - if (error < 0) - goto close_f12_inode; - i = error; - - error = get_unused_fd(); - if (error < 0) - goto close_f12_inode_i; - j = error; - - error = -ENOMEM; sprintf(name, "[%lu]", inode->i_ino); this.name = name; this.len = strlen(name); this.hash = inode->i_ino; /* will go */ + err = -ENOMEM; dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); if (!dentry) - goto close_f12_inode_i_j; + goto err_inode; dentry->d_op = &pipefs_dentry_operations; d_add(dentry, inode); - f1->f_vfsmnt = f2->f_vfsmnt = mntget(mntget(pipe_mnt)); - f1->f_dentry = f2->f_dentry = dget(dentry); - f1->f_mapping = f2->f_mapping = inode->i_mapping; - - /* read file */ - f1->f_pos = f2->f_pos = 0; - f1->f_flags = O_RDONLY; - f1->f_op = &read_pipe_fops; - f1->f_mode = FMODE_READ; - f1->f_version = 0; - - /* write file */ - f2->f_flags = O_WRONLY; - f2->f_op = &write_pipe_fops; - f2->f_mode = FMODE_WRITE; - f2->f_version = 0; - - fd_install(i, f1); - fd_install(j, f2); - fd[0] = i; - fd[1] = j; + f->f_vfsmnt = mntget(pipe_mnt); + f->f_dentry = dentry; + f->f_mapping = inode->i_mapping; - return 0; + f->f_flags = O_WRONLY; + f->f_op = &write_pipe_fops; + f->f_mode = FMODE_WRITE; + f->f_version = 0; -close_f12_inode_i_j: - put_unused_fd(j); -close_f12_inode_i: - put_unused_fd(i); -close_f12_inode: + return f; + + err_inode: free_pipe_info(inode); iput(inode); -close_f12: - put_filp(f2); -close_f1: - put_filp(f1); -no_files: - return error; + err_file: + put_filp(f); + return ERR_PTR(err); +} + +void free_write_pipe(struct file *f) +{ + mntput(f->f_vfsmnt); + dput(f->f_dentry); + put_filp(f); +} + +struct file *create_read_pipe(struct file *wrf) +{ + struct file *f = get_empty_filp(); + if (!f) + return ERR_PTR(-ENFILE); + + /* Grab pipe from the writer */ + f->f_vfsmnt = mntget(wrf->f_vfsmnt); + f->f_dentry = dget(wrf->f_dentry); + f->f_mapping = wrf->f_dentry->d_inode->i_mapping; + + f->f_pos = 0; + f->f_flags = O_RDONLY; + f->f_op = &read_pipe_fops; + f->f_mode = FMODE_READ; + f->f_version = 0; + + return f; +} + +int do_pipe(int *fd) +{ + struct file *fw, *fr; + int error; + int fdw, fdr; + + fw = create_write_pipe(); + if (IS_ERR(fw)) + return PTR_ERR(fw); + fr = create_read_pipe(fw); + error = PTR_ERR(fr); + if (IS_ERR(fr)) + goto err_write_pipe; + + error = get_unused_fd(); + if (error < 0) + goto err_read_pipe; + fdr = error; + + error = get_unused_fd(); + if (error < 0) + goto err_fdr; + fdw = error; + + fd_install(fdr, fr); + fd_install(fdw, fw); + fd[0] = fdr; + fd[1] = fdw; + + return 0; + + err_fdr: + put_unused_fd(fdr); + err_read_pipe: + put_filp(fr); + err_write_pipe: + free_write_pipe(fw); + return error; } /* -- cgit v1.2.3 From d025c9db7f31fc0554ce7fb2dfc78d35a77f3487 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 30 Sep 2006 23:29:28 -0700 Subject: [PATCH] Support piping into commands in /proc/sys/kernel/core_pattern Using the infrastructure created in previous patches implement support to pipe core dumps into programs. This is done by overloading the existing core_pattern sysctl with a new syntax: |program When the first character of the pattern is a '|' the kernel will instead threat the rest of the pattern as a command to run. The core dump will be written to the standard input of that program instead of to a file. This is useful for having automatic core dump analysis without filling up disks. The program can do some simple analysis and save only a summary of the core dump. The core dump proces will run with the privileges and in the name space of the process that caused the core dump. I also increased the core pattern size to 128 bytes so that longer command lines fit. Most of the changes comes from allowing core dumps without seeks. They are fairly straight forward though. One small incompatibility is that if someone had a core pattern previously that started with '|' they will get suddenly new behaviour. I think that's unlikely to be a real problem though. Additional background: > Very nice, do you happen to have a program that can accept this kind of > input for crash dumps? I'm guessing that the embedded people will > really want this functionality. I had a cheesy demo/prototype. Basically it wrote the dump to a file again, ran gdb on it to get a backtrace and wrote the summary to a shared directory. Then there was a simple CGI script to generate a "top 10" crashes HTML listing. Unfortunately this still had the disadvantage to needing full disk space for a dump except for deleting it afterwards (in fact it was worse because over the pipe holes didn't work so if you have a holey address map it would require more space). Fortunately gdb seems to be happy to handle /proc/pid/fd/xxx input pipes as cores (at least it worked with zsh's =(cat core) syntax), so it would be likely possible to do it without temporary space with a simple wrapper that calls it in the right way. I ran out of time before doing that though. The demo prototype scripts weren't very good. If there is really interest I can dig them out (they are currently on a laptop disk on the desk with the laptop itself being in service), but I would recommend to rewrite them for any serious application of this and fix the disk space problem. Also to be really useful it should probably find a way to automatically fetch the debuginfos (I cheated and just installed them in advance). If nobody else does it I can probably do the rewrite myself again at some point. My hope at some point was that desktops would support it in their builtin crash reporters, but at least the KDE people I talked too seemed to be happy with their user space only solution. Alan sayeth: I don't believe that piping as such as neccessarily the right model, but the ability to intercept and processes core dumps from user space is asked for by many enterprise users as well. They want to know about, capture, analyse and process core dumps, often centrally and in automated form. [akpm@osdl.org: loff_t != unsigned long] Signed-off-by: Andi Kleen Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/binfmt_elf.c | 77 +++++++++++++++++++++++++++++++++------------------------ fs/exec.c | 23 +++++++++++++---- 2 files changed, 63 insertions(+), 37 deletions(-) (limited to 'fs') diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index bad52433de6..06435f3665f 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1151,11 +1151,23 @@ static int dump_write(struct file *file, const void *addr, int nr) static int dump_seek(struct file *file, loff_t off) { - if (file->f_op->llseek) { - if (file->f_op->llseek(file, off, 0) != off) + if (file->f_op->llseek && file->f_op->llseek != no_llseek) { + if (file->f_op->llseek(file, off, 1) != off) return 0; - } else - file->f_pos = off; + } else { + char *buf = (char *)get_zeroed_page(GFP_KERNEL); + if (!buf) + return 0; + while (off > 0) { + unsigned long n = off; + if (n > PAGE_SIZE) + n = PAGE_SIZE; + if (!dump_write(file, buf, n)) + return 0; + off -= n; + } + free_page((unsigned long)buf); + } return 1; } @@ -1203,30 +1215,35 @@ static int notesize(struct memelfnote *en) return sz; } -#define DUMP_WRITE(addr, nr) \ - do { if (!dump_write(file, (addr), (nr))) return 0; } while(0) -#define DUMP_SEEK(off) \ - do { if (!dump_seek(file, (off))) return 0; } while(0) +#define DUMP_WRITE(addr, nr, foffset) \ + do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0) -static int writenote(struct memelfnote *men, struct file *file) +static int alignfile(struct file *file, loff_t *foffset) { - struct elf_note en; + char buf[4] = { 0, }; + DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset); + return 1; +} +static int writenote(struct memelfnote *men, struct file *file, + loff_t *foffset) +{ + struct elf_note en; en.n_namesz = strlen(men->name) + 1; en.n_descsz = men->datasz; en.n_type = men->type; - DUMP_WRITE(&en, sizeof(en)); - DUMP_WRITE(men->name, en.n_namesz); - /* XXX - cast from long long to long to avoid need for libgcc.a */ - DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ - DUMP_WRITE(men->data, men->datasz); - DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ + DUMP_WRITE(&en, sizeof(en), foffset); + DUMP_WRITE(men->name, en.n_namesz, foffset); + if (!alignfile(file, foffset)) + return 0; + DUMP_WRITE(men->data, men->datasz, foffset); + if (!alignfile(file, foffset)) + return 0; return 1; } #undef DUMP_WRITE -#undef DUMP_SEEK #define DUMP_WRITE(addr, nr) \ if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ @@ -1426,7 +1443,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) int i; struct vm_area_struct *vma; struct elfhdr *elf = NULL; - loff_t offset = 0, dataoff; + loff_t offset = 0, dataoff, foffset; unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; int numnote; struct memelfnote *notes = NULL; @@ -1569,7 +1586,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) DUMP_WRITE(&phdr, sizeof(phdr)); } - /* Page-align dumped data */ + foffset = offset; + dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); /* Write program headers for segments dump */ @@ -1594,6 +1612,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) phdr.p_align = ELF_EXEC_PAGESIZE; DUMP_WRITE(&phdr, sizeof(phdr)); + foffset += sizeof(phdr); } #ifdef ELF_CORE_WRITE_EXTRA_PHDRS @@ -1602,7 +1621,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) /* write out the notes section */ for (i = 0; i < numnote; i++) - if (!writenote(notes + i, file)) + if (!writenote(notes + i, file, &foffset)) goto end_coredump; /* write out the thread status notes section */ @@ -1611,11 +1630,12 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) list_entry(t, struct elf_thread_status, list); for (i = 0; i < tmp->num_notes; i++) - if (!writenote(&tmp->notes[i], file)) + if (!writenote(&tmp->notes[i], file, &foffset)) goto end_coredump; } - - DUMP_SEEK(dataoff); + + /* Align to page */ + DUMP_SEEK(dataoff - foffset); for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { unsigned long addr; @@ -1631,10 +1651,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) if (get_user_pages(current, current->mm, addr, 1, 0, 1, &page, &vma) <= 0) { - DUMP_SEEK(file->f_pos + PAGE_SIZE); + DUMP_SEEK(PAGE_SIZE); } else { if (page == ZERO_PAGE(addr)) { - DUMP_SEEK(file->f_pos + PAGE_SIZE); + DUMP_SEEK(PAGE_SIZE); } else { void *kaddr; flush_cache_page(vma, addr, @@ -1658,13 +1678,6 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) ELF_CORE_WRITE_EXTRA_DATA; #endif - if (file->f_pos != offset) { - /* Sanity check */ - printk(KERN_WARNING - "elf_core_dump: file->f_pos (%Ld) != offset (%Ld)\n", - file->f_pos, offset); - } - end_coredump: set_fs(fs); diff --git a/fs/exec.c b/fs/exec.c index 0db3fc3c5f0..6270f8f20a6 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -58,7 +58,7 @@ #endif int core_uses_pid; -char core_pattern[65] = "core"; +char core_pattern[128] = "core"; int suid_dumpable = 0; EXPORT_SYMBOL(suid_dumpable); @@ -1463,6 +1463,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) int retval = 0; int fsuid = current->fsuid; int flag = 0; + int ispipe = 0; binfmt = current->binfmt; if (!binfmt || !binfmt->core_dump) @@ -1504,22 +1505,34 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) lock_kernel(); format_corename(corename, core_pattern, signr); unlock_kernel(); - file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, 0600); + if (corename[0] == '|') { + /* SIGPIPE can happen, but it's just never processed */ + if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) { + printk(KERN_INFO "Core dump to %s pipe failed\n", + corename); + goto fail_unlock; + } + ispipe = 1; + } else + file = filp_open(corename, + O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); if (IS_ERR(file)) goto fail_unlock; inode = file->f_dentry->d_inode; if (inode->i_nlink > 1) goto close_fail; /* multiple links - don't dump */ - if (d_unhashed(file->f_dentry)) + if (!ispipe && d_unhashed(file->f_dentry)) goto close_fail; - if (!S_ISREG(inode->i_mode)) + /* AK: actually i see no reason to not allow this for named pipes etc., + but keep the previous behaviour for now. */ + if (!ispipe && !S_ISREG(inode->i_mode)) goto close_fail; if (!file->f_op) goto close_fail; if (!file->f_op->write) goto close_fail; - if (do_truncate(file->f_dentry, 0, 0, file) != 0) + if (!ispipe && do_truncate(file->f_dentry, 0, 0, file) != 0) goto close_fail; retval = binfmt->core_dump(signr, regs, file); -- cgit v1.2.3