mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 15:29:16 +00:00
Merge git://oss.sgi.com:8090/oss/git/xfs-2.6
* git://oss.sgi.com:8090/oss/git/xfs-2.6: (71 commits) [XFS] Sync up one/two other minor changes missed in previous merges. [XFS] Reenable the noikeep (delete inode cluster space) option by default. [XFS] Check that a page has dirty buffers before finding it acceptable for [XFS] Fixup naming inconsistencies found by Pekka Enberg and one from Jan [XFS] Explain the race closed by the addition of vn_iowait() to the start [XFS] Fixing the error caused by the conflict between DIO Write's [XFS] Fixing KDB's xrwtrc command, also added the current process id into [XFS] Fix compiler warning from xfs_file_compat_invis_ioctl prototype. [XFS] remove bogus INT_GET for u8 variables in xfs_dir_leaf.c [XFS] endianess annotations for xfs_da_node_hdr_t [XFS] endianess annotations for xfs_da_node_entry_t [XFS] store xfs_attr_inactive_list_t in native endian [XFS] store xfs_attr_sf_sort in native endian [XFS] endianess annotations for xfs_attr_shortform_t [XFS] endianess annotations for xfs_attr_leaf_name_remote_t [XFS] endianess annotations for xfs_attr_leaf_name_local_t [XFS] endianess annotations for xfs_attr_leaf_entry_t [XFS] endianess annotations for xfs_attr_leaf_hdr_t [XFS] remove bogus INT_GET on u8 variables in xfs_dir2_block.c [XFS] endianess annotations for xfs_da_blkinfo_t ...
This commit is contained in:
commit
debf798b1e
@ -1,33 +1,19 @@
|
||||
#
|
||||
# Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
|
||||
# Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of version 2 of the GNU General Public License as
|
||||
# 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.
|
||||
#
|
||||
# This program is distributed in the hope that it would be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# This program is distributed in the hope that it would be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# Further, this software is distributed without any warranty that it is
|
||||
# free of the rightful claim of any third person regarding infringement
|
||||
# or the like. Any license provided herein, whether implied or
|
||||
# otherwise, applies only to this software file. Patent licenses, if
|
||||
# any, provided herein do not apply to combinations of this program with
|
||||
# other software, or any other product whatsoever.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write the Free Software Foundation, Inc., 59
|
||||
# Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
#
|
||||
# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
|
||||
# Mountain View, CA 94043, or:
|
||||
#
|
||||
# http://www.sgi.com
|
||||
#
|
||||
# For further information regarding this notice, see:
|
||||
#
|
||||
# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
|
||||
EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char
|
||||
@ -36,7 +22,7 @@ XFS_LINUX := linux-2.6
|
||||
|
||||
ifeq ($(CONFIG_XFS_DEBUG),y)
|
||||
EXTRA_CFLAGS += -g -DSTATIC="" -DDEBUG
|
||||
EXTRA_CFLAGS += -DPAGEBUF_LOCK_TRACKING
|
||||
EXTRA_CFLAGS += -DXFS_BUF_LOCK_TRACKING
|
||||
endif
|
||||
ifeq ($(CONFIG_XFS_TRACE),y)
|
||||
EXTRA_CFLAGS += -DXFS_ALLOC_TRACE
|
||||
@ -50,7 +36,7 @@ ifeq ($(CONFIG_XFS_TRACE),y)
|
||||
EXTRA_CFLAGS += -DXFS_ILOCK_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_LOG_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_RW_TRACE
|
||||
EXTRA_CFLAGS += -DPAGEBUF_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_BUF_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_VNODE_TRACE
|
||||
endif
|
||||
|
||||
|
@ -23,17 +23,8 @@
|
||||
#include <linux/mm.h>
|
||||
|
||||
/*
|
||||
* memory management routines
|
||||
* Process flags handling
|
||||
*/
|
||||
#define KM_SLEEP 0x0001u
|
||||
#define KM_NOSLEEP 0x0002u
|
||||
#define KM_NOFS 0x0004u
|
||||
#define KM_MAYFAIL 0x0008u
|
||||
|
||||
#define kmem_zone kmem_cache
|
||||
#define kmem_zone_t struct kmem_cache
|
||||
|
||||
typedef unsigned long xfs_pflags_t;
|
||||
|
||||
#define PFLAGS_TEST_NOIO() (current->flags & PF_NOIO)
|
||||
#define PFLAGS_TEST_FSTRANS() (current->flags & PF_FSTRANS)
|
||||
@ -67,74 +58,102 @@ typedef unsigned long xfs_pflags_t;
|
||||
*(NSTATEP) = *(OSTATEP); \
|
||||
} while (0)
|
||||
|
||||
static __inline gfp_t kmem_flags_convert(unsigned int __nocast flags)
|
||||
{
|
||||
gfp_t lflags = __GFP_NOWARN; /* we'll report problems, if need be */
|
||||
/*
|
||||
* General memory allocation interfaces
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
if (unlikely(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL))) {
|
||||
printk(KERN_WARNING
|
||||
"XFS: memory allocation with wrong flags (%x)\n", flags);
|
||||
BUG();
|
||||
}
|
||||
#endif
|
||||
#define KM_SLEEP 0x0001u
|
||||
#define KM_NOSLEEP 0x0002u
|
||||
#define KM_NOFS 0x0004u
|
||||
#define KM_MAYFAIL 0x0008u
|
||||
|
||||
/*
|
||||
* We use a special process flag to avoid recursive callbacks into
|
||||
* the filesystem during transactions. We will also issue our own
|
||||
* warnings, so we explicitly skip any generic ones (silly of us).
|
||||
*/
|
||||
static inline gfp_t
|
||||
kmem_flags_convert(unsigned int __nocast flags)
|
||||
{
|
||||
gfp_t lflags;
|
||||
|
||||
BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL));
|
||||
|
||||
if (flags & KM_NOSLEEP) {
|
||||
lflags |= GFP_ATOMIC;
|
||||
lflags = GFP_ATOMIC | __GFP_NOWARN;
|
||||
} else {
|
||||
lflags |= GFP_KERNEL;
|
||||
|
||||
/* avoid recusive callbacks to filesystem during transactions */
|
||||
lflags = GFP_KERNEL | __GFP_NOWARN;
|
||||
if (PFLAGS_TEST_FSTRANS() || (flags & KM_NOFS))
|
||||
lflags &= ~__GFP_FS;
|
||||
}
|
||||
|
||||
return lflags;
|
||||
return lflags;
|
||||
}
|
||||
|
||||
static __inline kmem_zone_t *
|
||||
kmem_zone_init(int size, char *zone_name)
|
||||
{
|
||||
return kmem_cache_create(zone_name, size, 0, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
kmem_zone_free(kmem_zone_t *zone, void *ptr)
|
||||
{
|
||||
kmem_cache_free(zone, ptr);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
kmem_zone_destroy(kmem_zone_t *zone)
|
||||
{
|
||||
if (zone && kmem_cache_destroy(zone))
|
||||
BUG();
|
||||
}
|
||||
|
||||
extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);
|
||||
extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
|
||||
|
||||
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_free(void *, size_t);
|
||||
|
||||
/*
|
||||
* Zone interfaces
|
||||
*/
|
||||
|
||||
#define KM_ZONE_HWALIGN SLAB_HWCACHE_ALIGN
|
||||
#define KM_ZONE_RECLAIM SLAB_RECLAIM_ACCOUNT
|
||||
#define KM_ZONE_SPREAD 0
|
||||
|
||||
#define kmem_zone kmem_cache
|
||||
#define kmem_zone_t struct kmem_cache
|
||||
|
||||
static inline kmem_zone_t *
|
||||
kmem_zone_init(int size, char *zone_name)
|
||||
{
|
||||
return kmem_cache_create(zone_name, size, 0, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static inline kmem_zone_t *
|
||||
kmem_zone_init_flags(int size, char *zone_name, unsigned long flags,
|
||||
void (*construct)(void *, kmem_zone_t *, unsigned long))
|
||||
{
|
||||
return kmem_cache_create(zone_name, size, 0, flags, construct, NULL);
|
||||
}
|
||||
|
||||
static inline void
|
||||
kmem_zone_free(kmem_zone_t *zone, void *ptr)
|
||||
{
|
||||
kmem_cache_free(zone, ptr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
kmem_zone_destroy(kmem_zone_t *zone)
|
||||
{
|
||||
if (zone && kmem_cache_destroy(zone))
|
||||
BUG();
|
||||
}
|
||||
|
||||
extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
|
||||
extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);
|
||||
|
||||
/*
|
||||
* Low memory cache shrinkers
|
||||
*/
|
||||
|
||||
typedef struct shrinker *kmem_shaker_t;
|
||||
typedef int (*kmem_shake_func_t)(int, gfp_t);
|
||||
|
||||
static __inline kmem_shaker_t
|
||||
static inline kmem_shaker_t
|
||||
kmem_shake_register(kmem_shake_func_t sfunc)
|
||||
{
|
||||
return set_shrinker(DEFAULT_SEEKS, sfunc);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
static inline void
|
||||
kmem_shake_deregister(kmem_shaker_t shrinker)
|
||||
{
|
||||
remove_shrinker(shrinker);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
static inline int
|
||||
kmem_shake_allow(gfp_t gfp_mask)
|
||||
{
|
||||
return (gfp_mask & __GFP_WAIT);
|
||||
|
@ -43,7 +43,29 @@
|
||||
#include <linux/pagevec.h>
|
||||
#include <linux/writeback.h>
|
||||
|
||||
STATIC void xfs_count_page_state(struct page *, int *, int *, int *);
|
||||
STATIC void
|
||||
xfs_count_page_state(
|
||||
struct page *page,
|
||||
int *delalloc,
|
||||
int *unmapped,
|
||||
int *unwritten)
|
||||
{
|
||||
struct buffer_head *bh, *head;
|
||||
|
||||
*delalloc = *unmapped = *unwritten = 0;
|
||||
|
||||
bh = head = page_buffers(page);
|
||||
do {
|
||||
if (buffer_uptodate(bh) && !buffer_mapped(bh))
|
||||
(*unmapped) = 1;
|
||||
else if (buffer_unwritten(bh) && !buffer_delay(bh))
|
||||
clear_buffer_unwritten(bh);
|
||||
else if (buffer_unwritten(bh))
|
||||
(*unwritten) = 1;
|
||||
else if (buffer_delay(bh))
|
||||
(*delalloc) = 1;
|
||||
} while ((bh = bh->b_this_page) != head);
|
||||
}
|
||||
|
||||
#if defined(XFS_RW_TRACE)
|
||||
void
|
||||
@ -54,7 +76,7 @@ xfs_page_trace(
|
||||
int mask)
|
||||
{
|
||||
xfs_inode_t *ip;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
loff_t isize = i_size_read(inode);
|
||||
loff_t offset = page_offset(page);
|
||||
int delalloc = -1, unmapped = -1, unwritten = -1;
|
||||
@ -81,7 +103,7 @@ xfs_page_trace(
|
||||
(void *)((unsigned long)delalloc),
|
||||
(void *)((unsigned long)unmapped),
|
||||
(void *)((unsigned long)unwritten),
|
||||
(void *)NULL,
|
||||
(void *)((unsigned long)current_pid()),
|
||||
(void *)NULL);
|
||||
}
|
||||
#else
|
||||
@ -192,7 +214,7 @@ xfs_alloc_ioend(
|
||||
ioend->io_uptodate = 1; /* cleared if any I/O fails */
|
||||
ioend->io_list = NULL;
|
||||
ioend->io_type = type;
|
||||
ioend->io_vnode = LINVFS_GET_VP(inode);
|
||||
ioend->io_vnode = vn_from_inode(inode);
|
||||
ioend->io_buffer_head = NULL;
|
||||
ioend->io_buffer_tail = NULL;
|
||||
atomic_inc(&ioend->io_vnode->v_iocount);
|
||||
@ -217,7 +239,7 @@ xfs_map_blocks(
|
||||
xfs_iomap_t *mapp,
|
||||
int flags)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error, nmaps = 1;
|
||||
|
||||
VOP_BMAP(vp, offset, count, flags, mapp, &nmaps, error);
|
||||
@ -461,6 +483,26 @@ xfs_add_to_ioend(
|
||||
ioend->io_size += bh->b_size;
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_map_buffer(
|
||||
struct buffer_head *bh,
|
||||
xfs_iomap_t *mp,
|
||||
xfs_off_t offset,
|
||||
uint block_bits)
|
||||
{
|
||||
sector_t bn;
|
||||
|
||||
ASSERT(mp->iomap_bn != IOMAP_DADDR_NULL);
|
||||
|
||||
bn = (mp->iomap_bn >> (block_bits - BBSHIFT)) +
|
||||
((offset - mp->iomap_offset) >> block_bits);
|
||||
|
||||
ASSERT(bn || (mp->iomap_flags & IOMAP_REALTIME));
|
||||
|
||||
bh->b_blocknr = bn;
|
||||
set_buffer_mapped(bh);
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_map_at_offset(
|
||||
struct buffer_head *bh,
|
||||
@ -468,22 +510,11 @@ xfs_map_at_offset(
|
||||
int block_bits,
|
||||
xfs_iomap_t *iomapp)
|
||||
{
|
||||
xfs_daddr_t bn;
|
||||
int sector_shift;
|
||||
|
||||
ASSERT(!(iomapp->iomap_flags & IOMAP_HOLE));
|
||||
ASSERT(!(iomapp->iomap_flags & IOMAP_DELAY));
|
||||
ASSERT(iomapp->iomap_bn != IOMAP_DADDR_NULL);
|
||||
|
||||
sector_shift = block_bits - BBSHIFT;
|
||||
bn = (iomapp->iomap_bn >> sector_shift) +
|
||||
((offset - iomapp->iomap_offset) >> block_bits);
|
||||
|
||||
ASSERT(bn || (iomapp->iomap_flags & IOMAP_REALTIME));
|
||||
ASSERT((bn << sector_shift) >= iomapp->iomap_bn);
|
||||
|
||||
lock_buffer(bh);
|
||||
bh->b_blocknr = bn;
|
||||
xfs_map_buffer(bh, iomapp, offset, block_bits);
|
||||
bh->b_bdev = iomapp->iomap_target->bt_bdev;
|
||||
set_buffer_mapped(bh);
|
||||
clear_buffer_delay(bh);
|
||||
@ -616,7 +647,7 @@ xfs_is_delayed_page(
|
||||
acceptable = (type == IOMAP_UNWRITTEN);
|
||||
else if (buffer_delay(bh))
|
||||
acceptable = (type == IOMAP_DELAY);
|
||||
else if (buffer_mapped(bh))
|
||||
else if (buffer_dirty(bh) && buffer_mapped(bh))
|
||||
acceptable = (type == 0);
|
||||
else
|
||||
break;
|
||||
@ -1040,250 +1071,6 @@ error:
|
||||
return err;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
__linvfs_get_block(
|
||||
struct inode *inode,
|
||||
sector_t iblock,
|
||||
unsigned long blocks,
|
||||
struct buffer_head *bh_result,
|
||||
int create,
|
||||
int direct,
|
||||
bmapi_flags_t flags)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
xfs_iomap_t iomap;
|
||||
xfs_off_t offset;
|
||||
ssize_t size;
|
||||
int retpbbm = 1;
|
||||
int error;
|
||||
|
||||
offset = (xfs_off_t)iblock << inode->i_blkbits;
|
||||
if (blocks)
|
||||
size = (ssize_t) min_t(xfs_off_t, LONG_MAX,
|
||||
(xfs_off_t)blocks << inode->i_blkbits);
|
||||
else
|
||||
size = 1 << inode->i_blkbits;
|
||||
|
||||
VOP_BMAP(vp, offset, size,
|
||||
create ? flags : BMAPI_READ, &iomap, &retpbbm, error);
|
||||
if (error)
|
||||
return -error;
|
||||
|
||||
if (retpbbm == 0)
|
||||
return 0;
|
||||
|
||||
if (iomap.iomap_bn != IOMAP_DADDR_NULL) {
|
||||
xfs_daddr_t bn;
|
||||
xfs_off_t delta;
|
||||
|
||||
/* For unwritten extents do not report a disk address on
|
||||
* the read case (treat as if we're reading into a hole).
|
||||
*/
|
||||
if (create || !(iomap.iomap_flags & IOMAP_UNWRITTEN)) {
|
||||
delta = offset - iomap.iomap_offset;
|
||||
delta >>= inode->i_blkbits;
|
||||
|
||||
bn = iomap.iomap_bn >> (inode->i_blkbits - BBSHIFT);
|
||||
bn += delta;
|
||||
BUG_ON(!bn && !(iomap.iomap_flags & IOMAP_REALTIME));
|
||||
bh_result->b_blocknr = bn;
|
||||
set_buffer_mapped(bh_result);
|
||||
}
|
||||
if (create && (iomap.iomap_flags & IOMAP_UNWRITTEN)) {
|
||||
if (direct)
|
||||
bh_result->b_private = inode;
|
||||
set_buffer_unwritten(bh_result);
|
||||
set_buffer_delay(bh_result);
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a realtime file, data might be on a new device */
|
||||
bh_result->b_bdev = iomap.iomap_target->bt_bdev;
|
||||
|
||||
/* If we previously allocated a block out beyond eof and
|
||||
* we are now coming back to use it then we will need to
|
||||
* flag it as new even if it has a disk address.
|
||||
*/
|
||||
if (create &&
|
||||
((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
|
||||
(offset >= i_size_read(inode)) || (iomap.iomap_flags & IOMAP_NEW)))
|
||||
set_buffer_new(bh_result);
|
||||
|
||||
if (iomap.iomap_flags & IOMAP_DELAY) {
|
||||
BUG_ON(direct);
|
||||
if (create) {
|
||||
set_buffer_uptodate(bh_result);
|
||||
set_buffer_mapped(bh_result);
|
||||
set_buffer_delay(bh_result);
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks) {
|
||||
ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0);
|
||||
offset = min_t(xfs_off_t,
|
||||
iomap.iomap_bsize - iomap.iomap_delta,
|
||||
(xfs_off_t)blocks << inode->i_blkbits);
|
||||
bh_result->b_size = (u32) min_t(xfs_off_t, UINT_MAX, offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
linvfs_get_block(
|
||||
struct inode *inode,
|
||||
sector_t iblock,
|
||||
struct buffer_head *bh_result,
|
||||
int create)
|
||||
{
|
||||
return __linvfs_get_block(inode, iblock, 0, bh_result,
|
||||
create, 0, BMAPI_WRITE);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_get_blocks_direct(
|
||||
struct inode *inode,
|
||||
sector_t iblock,
|
||||
unsigned long max_blocks,
|
||||
struct buffer_head *bh_result,
|
||||
int create)
|
||||
{
|
||||
return __linvfs_get_block(inode, iblock, max_blocks, bh_result,
|
||||
create, 1, BMAPI_WRITE|BMAPI_DIRECT);
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_end_io_direct(
|
||||
struct kiocb *iocb,
|
||||
loff_t offset,
|
||||
ssize_t size,
|
||||
void *private)
|
||||
{
|
||||
xfs_ioend_t *ioend = iocb->private;
|
||||
|
||||
/*
|
||||
* Non-NULL private data means we need to issue a transaction to
|
||||
* convert a range from unwritten to written extents. This needs
|
||||
* to happen from process contect but aio+dio I/O completion
|
||||
* happens from irq context so we need to defer it to a workqueue.
|
||||
* This is not nessecary for synchronous direct I/O, but we do
|
||||
* it anyway to keep the code uniform and simpler.
|
||||
*
|
||||
* The core direct I/O code might be changed to always call the
|
||||
* completion handler in the future, in which case all this can
|
||||
* go away.
|
||||
*/
|
||||
if (private && size > 0) {
|
||||
ioend->io_offset = offset;
|
||||
ioend->io_size = size;
|
||||
xfs_finish_ioend(ioend);
|
||||
} else {
|
||||
ASSERT(size >= 0);
|
||||
xfs_destroy_ioend(ioend);
|
||||
}
|
||||
|
||||
/*
|
||||
* blockdev_direct_IO can return an error even afer the I/O
|
||||
* completion handler was called. Thus we need to protect
|
||||
* against double-freeing.
|
||||
*/
|
||||
iocb->private = NULL;
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_direct_IO(
|
||||
int rw,
|
||||
struct kiocb *iocb,
|
||||
const struct iovec *iov,
|
||||
loff_t offset,
|
||||
unsigned long nr_segs)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
xfs_iomap_t iomap;
|
||||
int maps = 1;
|
||||
int error;
|
||||
ssize_t ret;
|
||||
|
||||
VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error);
|
||||
if (error)
|
||||
return -error;
|
||||
|
||||
iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
|
||||
|
||||
ret = blockdev_direct_IO_own_locking(rw, iocb, inode,
|
||||
iomap.iomap_target->bt_bdev,
|
||||
iov, offset, nr_segs,
|
||||
linvfs_get_blocks_direct,
|
||||
linvfs_end_io_direct);
|
||||
|
||||
if (unlikely(ret <= 0 && iocb->private))
|
||||
xfs_destroy_ioend(iocb->private);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
STATIC sector_t
|
||||
linvfs_bmap(
|
||||
struct address_space *mapping,
|
||||
sector_t block)
|
||||
{
|
||||
struct inode *inode = (struct inode *)mapping->host;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
int error;
|
||||
|
||||
vn_trace_entry(vp, "linvfs_bmap", (inst_t *)__return_address);
|
||||
|
||||
VOP_RWLOCK(vp, VRWLOCK_READ);
|
||||
VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
|
||||
VOP_RWUNLOCK(vp, VRWLOCK_READ);
|
||||
return generic_block_bmap(mapping, block, linvfs_get_block);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_readpage(
|
||||
struct file *unused,
|
||||
struct page *page)
|
||||
{
|
||||
return mpage_readpage(page, linvfs_get_block);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_readpages(
|
||||
struct file *unused,
|
||||
struct address_space *mapping,
|
||||
struct list_head *pages,
|
||||
unsigned nr_pages)
|
||||
{
|
||||
return mpage_readpages(mapping, pages, nr_pages, linvfs_get_block);
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_count_page_state(
|
||||
struct page *page,
|
||||
int *delalloc,
|
||||
int *unmapped,
|
||||
int *unwritten)
|
||||
{
|
||||
struct buffer_head *bh, *head;
|
||||
|
||||
*delalloc = *unmapped = *unwritten = 0;
|
||||
|
||||
bh = head = page_buffers(page);
|
||||
do {
|
||||
if (buffer_uptodate(bh) && !buffer_mapped(bh))
|
||||
(*unmapped) = 1;
|
||||
else if (buffer_unwritten(bh) && !buffer_delay(bh))
|
||||
clear_buffer_unwritten(bh);
|
||||
else if (buffer_unwritten(bh))
|
||||
(*unwritten) = 1;
|
||||
else if (buffer_delay(bh))
|
||||
(*delalloc) = 1;
|
||||
} while ((bh = bh->b_this_page) != head);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* writepage: Called from one of two places:
|
||||
*
|
||||
@ -1305,7 +1092,7 @@ xfs_count_page_state(
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
linvfs_writepage(
|
||||
xfs_vm_writepage(
|
||||
struct page *page,
|
||||
struct writeback_control *wbc)
|
||||
{
|
||||
@ -1371,16 +1158,6 @@ out_unlock:
|
||||
return error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_invalidate_page(
|
||||
struct page *page,
|
||||
unsigned long offset)
|
||||
{
|
||||
xfs_page_trace(XFS_INVALIDPAGE_ENTER,
|
||||
page->mapping->host, page, offset);
|
||||
return block_invalidatepage(page, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to move a page into cleanable state - and from there
|
||||
* to be released. Possibly the page is already clean. We always
|
||||
@ -1401,7 +1178,7 @@ linvfs_invalidate_page(
|
||||
* free them and we should come back later via writepage.
|
||||
*/
|
||||
STATIC int
|
||||
linvfs_release_page(
|
||||
xfs_vm_releasepage(
|
||||
struct page *page,
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
@ -1414,6 +1191,9 @@ linvfs_release_page(
|
||||
|
||||
xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, gfp_mask);
|
||||
|
||||
if (!page_has_buffers(page))
|
||||
return 0;
|
||||
|
||||
xfs_count_page_state(page, &delalloc, &unmapped, &unwritten);
|
||||
if (!delalloc && !unwritten)
|
||||
goto free_buffers;
|
||||
@ -1443,25 +1223,245 @@ free_buffers:
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_prepare_write(
|
||||
__xfs_get_block(
|
||||
struct inode *inode,
|
||||
sector_t iblock,
|
||||
unsigned long blocks,
|
||||
struct buffer_head *bh_result,
|
||||
int create,
|
||||
int direct,
|
||||
bmapi_flags_t flags)
|
||||
{
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
xfs_iomap_t iomap;
|
||||
xfs_off_t offset;
|
||||
ssize_t size;
|
||||
int retpbbm = 1;
|
||||
int error;
|
||||
|
||||
offset = (xfs_off_t)iblock << inode->i_blkbits;
|
||||
if (blocks)
|
||||
size = (ssize_t) min_t(xfs_off_t, LONG_MAX,
|
||||
(xfs_off_t)blocks << inode->i_blkbits);
|
||||
else
|
||||
size = 1 << inode->i_blkbits;
|
||||
|
||||
VOP_BMAP(vp, offset, size,
|
||||
create ? flags : BMAPI_READ, &iomap, &retpbbm, error);
|
||||
if (error)
|
||||
return -error;
|
||||
|
||||
if (retpbbm == 0)
|
||||
return 0;
|
||||
|
||||
if (iomap.iomap_bn != IOMAP_DADDR_NULL) {
|
||||
/*
|
||||
* For unwritten extents do not report a disk address on
|
||||
* the read case (treat as if we're reading into a hole).
|
||||
*/
|
||||
if (create || !(iomap.iomap_flags & IOMAP_UNWRITTEN)) {
|
||||
xfs_map_buffer(bh_result, &iomap, offset,
|
||||
inode->i_blkbits);
|
||||
}
|
||||
if (create && (iomap.iomap_flags & IOMAP_UNWRITTEN)) {
|
||||
if (direct)
|
||||
bh_result->b_private = inode;
|
||||
set_buffer_unwritten(bh_result);
|
||||
set_buffer_delay(bh_result);
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a realtime file, data might be on a new device */
|
||||
bh_result->b_bdev = iomap.iomap_target->bt_bdev;
|
||||
|
||||
/* If we previously allocated a block out beyond eof and
|
||||
* we are now coming back to use it then we will need to
|
||||
* flag it as new even if it has a disk address.
|
||||
*/
|
||||
if (create &&
|
||||
((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
|
||||
(offset >= i_size_read(inode)) || (iomap.iomap_flags & IOMAP_NEW)))
|
||||
set_buffer_new(bh_result);
|
||||
|
||||
if (iomap.iomap_flags & IOMAP_DELAY) {
|
||||
BUG_ON(direct);
|
||||
if (create) {
|
||||
set_buffer_uptodate(bh_result);
|
||||
set_buffer_mapped(bh_result);
|
||||
set_buffer_delay(bh_result);
|
||||
}
|
||||
}
|
||||
|
||||
if (blocks) {
|
||||
ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0);
|
||||
offset = min_t(xfs_off_t,
|
||||
iomap.iomap_bsize - iomap.iomap_delta,
|
||||
(xfs_off_t)blocks << inode->i_blkbits);
|
||||
bh_result->b_size = (u32) min_t(xfs_off_t, UINT_MAX, offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_get_block(
|
||||
struct inode *inode,
|
||||
sector_t iblock,
|
||||
struct buffer_head *bh_result,
|
||||
int create)
|
||||
{
|
||||
return __xfs_get_block(inode, iblock, 0, bh_result,
|
||||
create, 0, BMAPI_WRITE);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_get_blocks_direct(
|
||||
struct inode *inode,
|
||||
sector_t iblock,
|
||||
unsigned long max_blocks,
|
||||
struct buffer_head *bh_result,
|
||||
int create)
|
||||
{
|
||||
return __xfs_get_block(inode, iblock, max_blocks, bh_result,
|
||||
create, 1, BMAPI_WRITE|BMAPI_DIRECT);
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_end_io_direct(
|
||||
struct kiocb *iocb,
|
||||
loff_t offset,
|
||||
ssize_t size,
|
||||
void *private)
|
||||
{
|
||||
xfs_ioend_t *ioend = iocb->private;
|
||||
|
||||
/*
|
||||
* Non-NULL private data means we need to issue a transaction to
|
||||
* convert a range from unwritten to written extents. This needs
|
||||
* to happen from process contect but aio+dio I/O completion
|
||||
* happens from irq context so we need to defer it to a workqueue.
|
||||
* This is not nessecary for synchronous direct I/O, but we do
|
||||
* it anyway to keep the code uniform and simpler.
|
||||
*
|
||||
* The core direct I/O code might be changed to always call the
|
||||
* completion handler in the future, in which case all this can
|
||||
* go away.
|
||||
*/
|
||||
if (private && size > 0) {
|
||||
ioend->io_offset = offset;
|
||||
ioend->io_size = size;
|
||||
xfs_finish_ioend(ioend);
|
||||
} else {
|
||||
ASSERT(size >= 0);
|
||||
xfs_destroy_ioend(ioend);
|
||||
}
|
||||
|
||||
/*
|
||||
* blockdev_direct_IO can return an error even afer the I/O
|
||||
* completion handler was called. Thus we need to protect
|
||||
* against double-freeing.
|
||||
*/
|
||||
iocb->private = NULL;
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
xfs_vm_direct_IO(
|
||||
int rw,
|
||||
struct kiocb *iocb,
|
||||
const struct iovec *iov,
|
||||
loff_t offset,
|
||||
unsigned long nr_segs)
|
||||
{
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
xfs_iomap_t iomap;
|
||||
int maps = 1;
|
||||
int error;
|
||||
ssize_t ret;
|
||||
|
||||
VOP_BMAP(vp, offset, 0, BMAPI_DEVICE, &iomap, &maps, error);
|
||||
if (error)
|
||||
return -error;
|
||||
|
||||
iocb->private = xfs_alloc_ioend(inode, IOMAP_UNWRITTEN);
|
||||
|
||||
ret = blockdev_direct_IO_own_locking(rw, iocb, inode,
|
||||
iomap.iomap_target->bt_bdev,
|
||||
iov, offset, nr_segs,
|
||||
xfs_get_blocks_direct,
|
||||
xfs_end_io_direct);
|
||||
|
||||
if (unlikely(ret <= 0 && iocb->private))
|
||||
xfs_destroy_ioend(iocb->private);
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_vm_prepare_write(
|
||||
struct file *file,
|
||||
struct page *page,
|
||||
unsigned int from,
|
||||
unsigned int to)
|
||||
{
|
||||
return block_prepare_write(page, from, to, linvfs_get_block);
|
||||
return block_prepare_write(page, from, to, xfs_get_block);
|
||||
}
|
||||
|
||||
struct address_space_operations linvfs_aops = {
|
||||
.readpage = linvfs_readpage,
|
||||
.readpages = linvfs_readpages,
|
||||
.writepage = linvfs_writepage,
|
||||
STATIC sector_t
|
||||
xfs_vm_bmap(
|
||||
struct address_space *mapping,
|
||||
sector_t block)
|
||||
{
|
||||
struct inode *inode = (struct inode *)mapping->host;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
|
||||
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
|
||||
|
||||
VOP_RWLOCK(vp, VRWLOCK_READ);
|
||||
VOP_FLUSH_PAGES(vp, (xfs_off_t)0, -1, 0, FI_REMAPF, error);
|
||||
VOP_RWUNLOCK(vp, VRWLOCK_READ);
|
||||
return generic_block_bmap(mapping, block, xfs_get_block);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_vm_readpage(
|
||||
struct file *unused,
|
||||
struct page *page)
|
||||
{
|
||||
return mpage_readpage(page, xfs_get_block);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_vm_readpages(
|
||||
struct file *unused,
|
||||
struct address_space *mapping,
|
||||
struct list_head *pages,
|
||||
unsigned nr_pages)
|
||||
{
|
||||
return mpage_readpages(mapping, pages, nr_pages, xfs_get_block);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_vm_invalidatepage(
|
||||
struct page *page,
|
||||
unsigned long offset)
|
||||
{
|
||||
xfs_page_trace(XFS_INVALIDPAGE_ENTER,
|
||||
page->mapping->host, page, offset);
|
||||
return block_invalidatepage(page, offset);
|
||||
}
|
||||
|
||||
struct address_space_operations xfs_address_space_operations = {
|
||||
.readpage = xfs_vm_readpage,
|
||||
.readpages = xfs_vm_readpages,
|
||||
.writepage = xfs_vm_writepage,
|
||||
.sync_page = block_sync_page,
|
||||
.releasepage = linvfs_release_page,
|
||||
.invalidatepage = linvfs_invalidate_page,
|
||||
.prepare_write = linvfs_prepare_write,
|
||||
.releasepage = xfs_vm_releasepage,
|
||||
.invalidatepage = xfs_vm_invalidatepage,
|
||||
.prepare_write = xfs_vm_prepare_write,
|
||||
.commit_write = generic_commit_write,
|
||||
.bmap = linvfs_bmap,
|
||||
.direct_IO = linvfs_direct_IO,
|
||||
.bmap = xfs_vm_bmap,
|
||||
.direct_IO = xfs_vm_direct_IO,
|
||||
.migratepage = buffer_migrate_page,
|
||||
};
|
||||
|
@ -40,7 +40,7 @@ typedef struct xfs_ioend {
|
||||
struct work_struct io_work; /* xfsdatad work queue */
|
||||
} xfs_ioend_t;
|
||||
|
||||
extern struct address_space_operations linvfs_aops;
|
||||
extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
||||
extern struct address_space_operations xfs_address_space_operations;
|
||||
extern int xfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
||||
|
||||
#endif /* __XFS_IOPS_H__ */
|
||||
|
@ -1806,13 +1806,12 @@ xfs_flush_buftarg(
|
||||
int __init
|
||||
xfs_buf_init(void)
|
||||
{
|
||||
int error = -ENOMEM;
|
||||
|
||||
#ifdef XFS_BUF_TRACE
|
||||
xfs_buf_trace_buf = ktrace_alloc(XFS_BUF_TRACE_SIZE, KM_SLEEP);
|
||||
#endif
|
||||
|
||||
xfs_buf_zone = kmem_zone_init(sizeof(xfs_buf_t), "xfs_buf");
|
||||
xfs_buf_zone = kmem_zone_init_flags(sizeof(xfs_buf_t), "xfs_buf",
|
||||
KM_ZONE_HWALIGN, NULL);
|
||||
if (!xfs_buf_zone)
|
||||
goto out_free_trace_buf;
|
||||
|
||||
@ -1840,7 +1839,7 @@ xfs_buf_init(void)
|
||||
#ifdef XFS_BUF_TRACE
|
||||
ktrace_free(xfs_buf_trace_buf);
|
||||
#endif
|
||||
return error;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_export.h"
|
||||
|
||||
STATIC struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
|
||||
|
||||
/*
|
||||
* XFS encodes and decodes the fileid portion of NFS filehandles
|
||||
* itself instead of letting the generic NFS code do it. This
|
||||
@ -37,7 +39,7 @@
|
||||
*/
|
||||
|
||||
STATIC struct dentry *
|
||||
linvfs_decode_fh(
|
||||
xfs_fs_decode_fh(
|
||||
struct super_block *sb,
|
||||
__u32 *fh,
|
||||
int fh_len,
|
||||
@ -78,12 +80,12 @@ linvfs_decode_fh(
|
||||
}
|
||||
|
||||
fh = (__u32 *)&ifid;
|
||||
return find_exported_dentry(sb, fh, parent, acceptable, context);
|
||||
return sb->s_export_op->find_exported_dentry(sb, fh, parent, acceptable, context);
|
||||
}
|
||||
|
||||
|
||||
STATIC int
|
||||
linvfs_encode_fh(
|
||||
xfs_fs_encode_fh(
|
||||
struct dentry *dentry,
|
||||
__u32 *fh,
|
||||
int *max_len,
|
||||
@ -95,7 +97,7 @@ linvfs_encode_fh(
|
||||
int len;
|
||||
int is64 = 0;
|
||||
#if XFS_BIG_INUMS
|
||||
vfs_t *vfs = LINVFS_GET_VFS(inode->i_sb);
|
||||
vfs_t *vfs = vfs_from_sb(inode->i_sb);
|
||||
|
||||
if (!(vfs->vfs_flag & VFS_32BITINODES)) {
|
||||
/* filesystem may contain 64bit inode numbers */
|
||||
@ -130,21 +132,21 @@ linvfs_encode_fh(
|
||||
}
|
||||
|
||||
STATIC struct dentry *
|
||||
linvfs_get_dentry(
|
||||
xfs_fs_get_dentry(
|
||||
struct super_block *sb,
|
||||
void *data)
|
||||
{
|
||||
vnode_t *vp;
|
||||
struct inode *inode;
|
||||
struct dentry *result;
|
||||
vfs_t *vfsp = LINVFS_GET_VFS(sb);
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_VGET(vfsp, &vp, (fid_t *)data, error);
|
||||
if (error || vp == NULL)
|
||||
return ERR_PTR(-ESTALE) ;
|
||||
|
||||
inode = LINVFS_GET_IP(vp);
|
||||
inode = vn_to_inode(vp);
|
||||
result = d_alloc_anon(inode);
|
||||
if (!result) {
|
||||
iput(inode);
|
||||
@ -154,25 +156,20 @@ linvfs_get_dentry(
|
||||
}
|
||||
|
||||
STATIC struct dentry *
|
||||
linvfs_get_parent(
|
||||
xfs_fs_get_parent(
|
||||
struct dentry *child)
|
||||
{
|
||||
int error;
|
||||
vnode_t *vp, *cvp;
|
||||
struct dentry *parent;
|
||||
struct dentry dotdot;
|
||||
|
||||
dotdot.d_name.name = "..";
|
||||
dotdot.d_name.len = 2;
|
||||
dotdot.d_inode = NULL;
|
||||
|
||||
cvp = NULL;
|
||||
vp = LINVFS_GET_VP(child->d_inode);
|
||||
vp = vn_from_inode(child->d_inode);
|
||||
VOP_LOOKUP(vp, &dotdot, &cvp, 0, NULL, NULL, error);
|
||||
if (unlikely(error))
|
||||
return ERR_PTR(-error);
|
||||
|
||||
parent = d_alloc_anon(LINVFS_GET_IP(cvp));
|
||||
parent = d_alloc_anon(vn_to_inode(cvp));
|
||||
if (unlikely(!parent)) {
|
||||
VN_RELE(cvp);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
@ -180,9 +177,9 @@ linvfs_get_parent(
|
||||
return parent;
|
||||
}
|
||||
|
||||
struct export_operations linvfs_export_ops = {
|
||||
.decode_fh = linvfs_decode_fh,
|
||||
.encode_fh = linvfs_encode_fh,
|
||||
.get_parent = linvfs_get_parent,
|
||||
.get_dentry = linvfs_get_dentry,
|
||||
struct export_operations xfs_export_operations = {
|
||||
.decode_fh = xfs_fs_decode_fh,
|
||||
.encode_fh = xfs_fs_encode_fh,
|
||||
.get_parent = xfs_fs_get_parent,
|
||||
.get_dentry = xfs_fs_get_dentry,
|
||||
};
|
||||
|
@ -43,13 +43,13 @@
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/smp_lock.h>
|
||||
|
||||
static struct vm_operations_struct linvfs_file_vm_ops;
|
||||
static struct vm_operations_struct xfs_file_vm_ops;
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
static struct vm_operations_struct linvfs_dmapi_file_vm_ops;
|
||||
static struct vm_operations_struct xfs_dmapi_file_vm_ops;
|
||||
#endif
|
||||
|
||||
STATIC inline ssize_t
|
||||
__linvfs_read(
|
||||
__xfs_file_read(
|
||||
struct kiocb *iocb,
|
||||
char __user *buf,
|
||||
int ioflags,
|
||||
@ -58,7 +58,7 @@ __linvfs_read(
|
||||
{
|
||||
struct iovec iov = {buf, count};
|
||||
struct file *file = iocb->ki_filp;
|
||||
vnode_t *vp = LINVFS_GET_VP(file->f_dentry->d_inode);
|
||||
vnode_t *vp = vn_from_inode(file->f_dentry->d_inode);
|
||||
ssize_t rval;
|
||||
|
||||
BUG_ON(iocb->ki_pos != pos);
|
||||
@ -71,28 +71,28 @@ __linvfs_read(
|
||||
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_aio_read(
|
||||
xfs_file_aio_read(
|
||||
struct kiocb *iocb,
|
||||
char __user *buf,
|
||||
size_t count,
|
||||
loff_t pos)
|
||||
{
|
||||
return __linvfs_read(iocb, buf, IO_ISAIO, count, pos);
|
||||
return __xfs_file_read(iocb, buf, IO_ISAIO, count, pos);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_aio_read_invis(
|
||||
xfs_file_aio_read_invis(
|
||||
struct kiocb *iocb,
|
||||
char __user *buf,
|
||||
size_t count,
|
||||
loff_t pos)
|
||||
{
|
||||
return __linvfs_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
|
||||
return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
|
||||
}
|
||||
|
||||
|
||||
STATIC inline ssize_t
|
||||
__linvfs_write(
|
||||
__xfs_file_write(
|
||||
struct kiocb *iocb,
|
||||
const char __user *buf,
|
||||
int ioflags,
|
||||
@ -102,7 +102,7 @@ __linvfs_write(
|
||||
struct iovec iov = {(void __user *)buf, count};
|
||||
struct file *file = iocb->ki_filp;
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
ssize_t rval;
|
||||
|
||||
BUG_ON(iocb->ki_pos != pos);
|
||||
@ -115,28 +115,28 @@ __linvfs_write(
|
||||
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_aio_write(
|
||||
xfs_file_aio_write(
|
||||
struct kiocb *iocb,
|
||||
const char __user *buf,
|
||||
size_t count,
|
||||
loff_t pos)
|
||||
{
|
||||
return __linvfs_write(iocb, buf, IO_ISAIO, count, pos);
|
||||
return __xfs_file_write(iocb, buf, IO_ISAIO, count, pos);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_aio_write_invis(
|
||||
xfs_file_aio_write_invis(
|
||||
struct kiocb *iocb,
|
||||
const char __user *buf,
|
||||
size_t count,
|
||||
loff_t pos)
|
||||
{
|
||||
return __linvfs_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
|
||||
return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
|
||||
}
|
||||
|
||||
|
||||
STATIC inline ssize_t
|
||||
__linvfs_readv(
|
||||
__xfs_file_readv(
|
||||
struct file *file,
|
||||
const struct iovec *iov,
|
||||
int ioflags,
|
||||
@ -144,8 +144,8 @@ __linvfs_readv(
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
struct kiocb kiocb;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
struct kiocb kiocb;
|
||||
ssize_t rval;
|
||||
|
||||
init_sync_kiocb(&kiocb, file);
|
||||
@ -160,28 +160,28 @@ __linvfs_readv(
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_readv(
|
||||
xfs_file_readv(
|
||||
struct file *file,
|
||||
const struct iovec *iov,
|
||||
unsigned long nr_segs,
|
||||
loff_t *ppos)
|
||||
{
|
||||
return __linvfs_readv(file, iov, 0, nr_segs, ppos);
|
||||
return __xfs_file_readv(file, iov, 0, nr_segs, ppos);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_readv_invis(
|
||||
xfs_file_readv_invis(
|
||||
struct file *file,
|
||||
const struct iovec *iov,
|
||||
unsigned long nr_segs,
|
||||
loff_t *ppos)
|
||||
{
|
||||
return __linvfs_readv(file, iov, IO_INVIS, nr_segs, ppos);
|
||||
return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos);
|
||||
}
|
||||
|
||||
|
||||
STATIC inline ssize_t
|
||||
__linvfs_writev(
|
||||
__xfs_file_writev(
|
||||
struct file *file,
|
||||
const struct iovec *iov,
|
||||
int ioflags,
|
||||
@ -189,8 +189,8 @@ __linvfs_writev(
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
struct kiocb kiocb;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
struct kiocb kiocb;
|
||||
ssize_t rval;
|
||||
|
||||
init_sync_kiocb(&kiocb, file);
|
||||
@ -206,34 +206,34 @@ __linvfs_writev(
|
||||
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_writev(
|
||||
xfs_file_writev(
|
||||
struct file *file,
|
||||
const struct iovec *iov,
|
||||
unsigned long nr_segs,
|
||||
loff_t *ppos)
|
||||
{
|
||||
return __linvfs_writev(file, iov, 0, nr_segs, ppos);
|
||||
return __xfs_file_writev(file, iov, 0, nr_segs, ppos);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_writev_invis(
|
||||
xfs_file_writev_invis(
|
||||
struct file *file,
|
||||
const struct iovec *iov,
|
||||
unsigned long nr_segs,
|
||||
loff_t *ppos)
|
||||
{
|
||||
return __linvfs_writev(file, iov, IO_INVIS, nr_segs, ppos);
|
||||
return __xfs_file_writev(file, iov, IO_INVIS, nr_segs, ppos);
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_sendfile(
|
||||
xfs_file_sendfile(
|
||||
struct file *filp,
|
||||
loff_t *ppos,
|
||||
size_t count,
|
||||
read_actor_t actor,
|
||||
void *target)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
|
||||
vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
|
||||
ssize_t rval;
|
||||
|
||||
VOP_SENDFILE(vp, filp, ppos, 0, count, actor, target, NULL, rval);
|
||||
@ -242,11 +242,11 @@ linvfs_sendfile(
|
||||
|
||||
|
||||
STATIC int
|
||||
linvfs_open(
|
||||
xfs_file_open(
|
||||
struct inode *inode,
|
||||
struct file *filp)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
|
||||
if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
|
||||
@ -259,11 +259,11 @@ linvfs_open(
|
||||
|
||||
|
||||
STATIC int
|
||||
linvfs_release(
|
||||
xfs_file_release(
|
||||
struct inode *inode,
|
||||
struct file *filp)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error = 0;
|
||||
|
||||
if (vp)
|
||||
@ -273,13 +273,13 @@ linvfs_release(
|
||||
|
||||
|
||||
STATIC int
|
||||
linvfs_fsync(
|
||||
xfs_file_fsync(
|
||||
struct file *filp,
|
||||
struct dentry *dentry,
|
||||
int datasync)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
int flags = FSYNC_WAIT;
|
||||
|
||||
@ -292,7 +292,7 @@ linvfs_fsync(
|
||||
}
|
||||
|
||||
/*
|
||||
* linvfs_readdir maps to VOP_READDIR().
|
||||
* xfs_file_readdir maps to VOP_READDIR().
|
||||
* We need to build a uio, cred, ...
|
||||
*/
|
||||
|
||||
@ -301,13 +301,13 @@ linvfs_fsync(
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
|
||||
STATIC struct page *
|
||||
linvfs_filemap_nopage(
|
||||
xfs_vm_nopage(
|
||||
struct vm_area_struct *area,
|
||||
unsigned long address,
|
||||
int *type)
|
||||
{
|
||||
struct inode *inode = area->vm_file->f_dentry->d_inode;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
|
||||
int error;
|
||||
|
||||
@ -324,7 +324,7 @@ linvfs_filemap_nopage(
|
||||
|
||||
|
||||
STATIC int
|
||||
linvfs_readdir(
|
||||
xfs_file_readdir(
|
||||
struct file *filp,
|
||||
void *dirent,
|
||||
filldir_t filldir)
|
||||
@ -340,7 +340,7 @@ linvfs_readdir(
|
||||
xfs_off_t start_offset, curr_offset;
|
||||
xfs_dirent_t *dbp = NULL;
|
||||
|
||||
vp = LINVFS_GET_VP(filp->f_dentry->d_inode);
|
||||
vp = vn_from_inode(filp->f_dentry->d_inode);
|
||||
ASSERT(vp);
|
||||
|
||||
/* Try fairly hard to get memory */
|
||||
@ -404,39 +404,40 @@ done:
|
||||
|
||||
|
||||
STATIC int
|
||||
linvfs_file_mmap(
|
||||
xfs_file_mmap(
|
||||
struct file *filp,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct inode *ip = filp->f_dentry->d_inode;
|
||||
vnode_t *vp = LINVFS_GET_VP(ip);
|
||||
vattr_t va = { .va_mask = XFS_AT_UPDATIME };
|
||||
vnode_t *vp = vn_from_inode(ip);
|
||||
vattr_t vattr;
|
||||
int error;
|
||||
|
||||
vma->vm_ops = &linvfs_file_vm_ops;
|
||||
vma->vm_ops = &xfs_file_vm_ops;
|
||||
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
if (vp->v_vfsp->vfs_flag & VFS_DMI) {
|
||||
vma->vm_ops = &linvfs_dmapi_file_vm_ops;
|
||||
vma->vm_ops = &xfs_dmapi_file_vm_ops;
|
||||
}
|
||||
#endif /* CONFIG_XFS_DMAPI */
|
||||
|
||||
VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
|
||||
if (!error)
|
||||
vn_revalidate(vp); /* update Linux inode flags */
|
||||
vattr.va_mask = XFS_AT_UPDATIME;
|
||||
VOP_SETATTR(vp, &vattr, XFS_AT_UPDATIME, NULL, error);
|
||||
if (likely(!error))
|
||||
__vn_revalidate(vp, &vattr); /* update flags */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
STATIC long
|
||||
linvfs_ioctl(
|
||||
xfs_file_ioctl(
|
||||
struct file *filp,
|
||||
unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int error;
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
VOP_IOCTL(vp, inode, filp, 0, cmd, (void __user *)arg, error);
|
||||
VMODIFY(vp);
|
||||
@ -451,14 +452,14 @@ linvfs_ioctl(
|
||||
}
|
||||
|
||||
STATIC long
|
||||
linvfs_ioctl_invis(
|
||||
xfs_file_ioctl_invis(
|
||||
struct file *filp,
|
||||
unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int error;
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
struct inode *inode = filp->f_dentry->d_inode;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
|
||||
ASSERT(vp);
|
||||
VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error);
|
||||
@ -476,11 +477,11 @@ linvfs_ioctl_invis(
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
#ifdef HAVE_VMOP_MPROTECT
|
||||
STATIC int
|
||||
linvfs_mprotect(
|
||||
xfs_vm_mprotect(
|
||||
struct vm_area_struct *vma,
|
||||
unsigned int newflags)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(vma->vm_file->f_dentry->d_inode);
|
||||
vnode_t *vp = vn_from_inode(vma->vm_file->f_dentry->d_inode);
|
||||
int error = 0;
|
||||
|
||||
if (vp->v_vfsp->vfs_flag & VFS_DMI) {
|
||||
@ -503,10 +504,10 @@ linvfs_mprotect(
|
||||
* it back online.
|
||||
*/
|
||||
STATIC int
|
||||
linvfs_open_exec(
|
||||
xfs_file_open_exec(
|
||||
struct inode *inode)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
xfs_mount_t *mp = XFS_VFSTOM(vp->v_vfsp);
|
||||
int error = 0;
|
||||
xfs_inode_t *ip;
|
||||
@ -527,69 +528,69 @@ open_exec_out:
|
||||
}
|
||||
#endif /* HAVE_FOP_OPEN_EXEC */
|
||||
|
||||
struct file_operations linvfs_file_operations = {
|
||||
struct file_operations xfs_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = do_sync_read,
|
||||
.write = do_sync_write,
|
||||
.readv = linvfs_readv,
|
||||
.writev = linvfs_writev,
|
||||
.aio_read = linvfs_aio_read,
|
||||
.aio_write = linvfs_aio_write,
|
||||
.sendfile = linvfs_sendfile,
|
||||
.unlocked_ioctl = linvfs_ioctl,
|
||||
.readv = xfs_file_readv,
|
||||
.writev = xfs_file_writev,
|
||||
.aio_read = xfs_file_aio_read,
|
||||
.aio_write = xfs_file_aio_write,
|
||||
.sendfile = xfs_file_sendfile,
|
||||
.unlocked_ioctl = xfs_file_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = linvfs_compat_ioctl,
|
||||
.compat_ioctl = xfs_file_compat_ioctl,
|
||||
#endif
|
||||
.mmap = linvfs_file_mmap,
|
||||
.open = linvfs_open,
|
||||
.release = linvfs_release,
|
||||
.fsync = linvfs_fsync,
|
||||
.mmap = xfs_file_mmap,
|
||||
.open = xfs_file_open,
|
||||
.release = xfs_file_release,
|
||||
.fsync = xfs_file_fsync,
|
||||
#ifdef HAVE_FOP_OPEN_EXEC
|
||||
.open_exec = linvfs_open_exec,
|
||||
.open_exec = xfs_file_open_exec,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct file_operations linvfs_invis_file_operations = {
|
||||
struct file_operations xfs_invis_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = do_sync_read,
|
||||
.write = do_sync_write,
|
||||
.readv = linvfs_readv_invis,
|
||||
.writev = linvfs_writev_invis,
|
||||
.aio_read = linvfs_aio_read_invis,
|
||||
.aio_write = linvfs_aio_write_invis,
|
||||
.sendfile = linvfs_sendfile,
|
||||
.unlocked_ioctl = linvfs_ioctl_invis,
|
||||
.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,
|
||||
.unlocked_ioctl = xfs_file_ioctl_invis,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = linvfs_compat_invis_ioctl,
|
||||
.compat_ioctl = xfs_file_compat_invis_ioctl,
|
||||
#endif
|
||||
.mmap = linvfs_file_mmap,
|
||||
.open = linvfs_open,
|
||||
.release = linvfs_release,
|
||||
.fsync = linvfs_fsync,
|
||||
.mmap = xfs_file_mmap,
|
||||
.open = xfs_file_open,
|
||||
.release = xfs_file_release,
|
||||
.fsync = xfs_file_fsync,
|
||||
};
|
||||
|
||||
|
||||
struct file_operations linvfs_dir_operations = {
|
||||
struct file_operations xfs_dir_file_operations = {
|
||||
.read = generic_read_dir,
|
||||
.readdir = linvfs_readdir,
|
||||
.unlocked_ioctl = linvfs_ioctl,
|
||||
.readdir = xfs_file_readdir,
|
||||
.unlocked_ioctl = xfs_file_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = linvfs_compat_ioctl,
|
||||
.compat_ioctl = xfs_file_compat_ioctl,
|
||||
#endif
|
||||
.fsync = linvfs_fsync,
|
||||
.fsync = xfs_file_fsync,
|
||||
};
|
||||
|
||||
static struct vm_operations_struct linvfs_file_vm_ops = {
|
||||
static struct vm_operations_struct xfs_file_vm_ops = {
|
||||
.nopage = filemap_nopage,
|
||||
.populate = filemap_populate,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
static struct vm_operations_struct linvfs_dmapi_file_vm_ops = {
|
||||
.nopage = linvfs_filemap_nopage,
|
||||
static struct vm_operations_struct xfs_dmapi_file_vm_ops = {
|
||||
.nopage = xfs_vm_nopage,
|
||||
.populate = filemap_populate,
|
||||
#ifdef HAVE_VMOP_MPROTECT
|
||||
.mprotect = linvfs_mprotect,
|
||||
.mprotect = xfs_vm_mprotect,
|
||||
#endif
|
||||
};
|
||||
#endif /* CONFIG_XFS_DMAPI */
|
||||
|
@ -57,7 +57,7 @@ fs_tosspages(
|
||||
int fiopt)
|
||||
{
|
||||
vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
struct inode *ip = LINVFS_GET_IP(vp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
|
||||
if (VN_CACHED(vp))
|
||||
truncate_inode_pages(ip->i_mapping, first);
|
||||
@ -76,7 +76,7 @@ fs_flushinval_pages(
|
||||
int fiopt)
|
||||
{
|
||||
vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
struct inode *ip = LINVFS_GET_IP(vp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
|
||||
if (VN_CACHED(vp)) {
|
||||
filemap_write_and_wait(ip->i_mapping);
|
||||
@ -98,7 +98,7 @@ fs_flush_pages(
|
||||
int fiopt)
|
||||
{
|
||||
vnode_t *vp = BHV_TO_VNODE(bdp);
|
||||
struct inode *ip = LINVFS_GET_IP(vp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
|
||||
if (VN_CACHED(vp)) {
|
||||
filemap_fdatawrite(ip->i_mapping);
|
||||
|
@ -138,7 +138,7 @@ xfs_find_handle(
|
||||
}
|
||||
|
||||
/* we need the vnode */
|
||||
vp = LINVFS_GET_VP(inode);
|
||||
vp = vn_from_inode(inode);
|
||||
|
||||
/* now we can grab the fsid */
|
||||
memcpy(&handle.ha_fsid, vp->v_vfsp->vfs_altfsid, sizeof(xfs_fsid_t));
|
||||
@ -256,7 +256,7 @@ xfs_vget_fsop_handlereq(
|
||||
}
|
||||
|
||||
vpp = XFS_ITOV(ip);
|
||||
inodep = LINVFS_GET_IP(vpp);
|
||||
inodep = vn_to_inode(vpp);
|
||||
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
||||
|
||||
*vp = vpp;
|
||||
@ -344,7 +344,7 @@ xfs_open_by_handle(
|
||||
return -XFS_ERROR(-PTR_ERR(filp));
|
||||
}
|
||||
if (inode->i_mode & S_IFREG)
|
||||
filp->f_op = &linvfs_invis_file_operations;
|
||||
filp->f_op = &xfs_invis_file_operations;
|
||||
|
||||
fd_install(new_fd, filp);
|
||||
return new_fd;
|
||||
@ -715,7 +715,7 @@ xfs_ioctl(
|
||||
xfs_inode_t *ip;
|
||||
xfs_mount_t *mp;
|
||||
|
||||
vp = LINVFS_GET_VP(inode);
|
||||
vp = vn_from_inode(inode);
|
||||
|
||||
vn_trace_entry(vp, "xfs_ioctl", (inst_t *)__return_address);
|
||||
|
||||
@ -1160,105 +1160,129 @@ xfs_ioc_xattr(
|
||||
void __user *arg)
|
||||
{
|
||||
struct fsxattr fa;
|
||||
vattr_t va;
|
||||
int error;
|
||||
struct vattr *vattr;
|
||||
int error = 0;
|
||||
int attr_flags;
|
||||
unsigned int flags;
|
||||
|
||||
vattr = kmalloc(sizeof(*vattr), GFP_KERNEL);
|
||||
if (unlikely(!vattr))
|
||||
return -ENOMEM;
|
||||
|
||||
switch (cmd) {
|
||||
case XFS_IOC_FSGETXATTR: {
|
||||
va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
|
||||
XFS_AT_NEXTENTS | XFS_AT_PROJID;
|
||||
VOP_GETATTR(vp, &va, 0, NULL, error);
|
||||
if (error)
|
||||
return -error;
|
||||
vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
|
||||
XFS_AT_NEXTENTS | XFS_AT_PROJID;
|
||||
VOP_GETATTR(vp, vattr, 0, NULL, error);
|
||||
if (unlikely(error)) {
|
||||
error = -error;
|
||||
break;
|
||||
}
|
||||
|
||||
fa.fsx_xflags = va.va_xflags;
|
||||
fa.fsx_extsize = va.va_extsize;
|
||||
fa.fsx_nextents = va.va_nextents;
|
||||
fa.fsx_projid = va.va_projid;
|
||||
fa.fsx_xflags = vattr->va_xflags;
|
||||
fa.fsx_extsize = vattr->va_extsize;
|
||||
fa.fsx_nextents = vattr->va_nextents;
|
||||
fa.fsx_projid = vattr->va_projid;
|
||||
|
||||
if (copy_to_user(arg, &fa, sizeof(fa)))
|
||||
return -XFS_ERROR(EFAULT);
|
||||
return 0;
|
||||
if (copy_to_user(arg, &fa, sizeof(fa))) {
|
||||
error = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case XFS_IOC_FSSETXATTR: {
|
||||
if (copy_from_user(&fa, arg, sizeof(fa)))
|
||||
return -XFS_ERROR(EFAULT);
|
||||
if (copy_from_user(&fa, arg, sizeof(fa))) {
|
||||
error = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
attr_flags = 0;
|
||||
if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
|
||||
attr_flags |= ATTR_NONBLOCK;
|
||||
|
||||
va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
|
||||
va.va_xflags = fa.fsx_xflags;
|
||||
va.va_extsize = fa.fsx_extsize;
|
||||
va.va_projid = fa.fsx_projid;
|
||||
vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
|
||||
vattr->va_xflags = fa.fsx_xflags;
|
||||
vattr->va_extsize = fa.fsx_extsize;
|
||||
vattr->va_projid = fa.fsx_projid;
|
||||
|
||||
VOP_SETATTR(vp, &va, attr_flags, NULL, error);
|
||||
if (!error)
|
||||
vn_revalidate(vp); /* update Linux inode flags */
|
||||
return -error;
|
||||
VOP_SETATTR(vp, vattr, attr_flags, NULL, error);
|
||||
if (likely(!error))
|
||||
__vn_revalidate(vp, vattr); /* update flags */
|
||||
error = -error;
|
||||
break;
|
||||
}
|
||||
|
||||
case XFS_IOC_FSGETXATTRA: {
|
||||
va.va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
|
||||
XFS_AT_ANEXTENTS | XFS_AT_PROJID;
|
||||
VOP_GETATTR(vp, &va, 0, NULL, error);
|
||||
if (error)
|
||||
return -error;
|
||||
vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
|
||||
XFS_AT_ANEXTENTS | XFS_AT_PROJID;
|
||||
VOP_GETATTR(vp, vattr, 0, NULL, error);
|
||||
if (unlikely(error)) {
|
||||
error = -error;
|
||||
break;
|
||||
}
|
||||
|
||||
fa.fsx_xflags = va.va_xflags;
|
||||
fa.fsx_extsize = va.va_extsize;
|
||||
fa.fsx_nextents = va.va_anextents;
|
||||
fa.fsx_projid = va.va_projid;
|
||||
fa.fsx_xflags = vattr->va_xflags;
|
||||
fa.fsx_extsize = vattr->va_extsize;
|
||||
fa.fsx_nextents = vattr->va_anextents;
|
||||
fa.fsx_projid = vattr->va_projid;
|
||||
|
||||
if (copy_to_user(arg, &fa, sizeof(fa)))
|
||||
return -XFS_ERROR(EFAULT);
|
||||
return 0;
|
||||
if (copy_to_user(arg, &fa, sizeof(fa))) {
|
||||
error = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case XFS_IOC_GETXFLAGS: {
|
||||
flags = xfs_di2lxflags(ip->i_d.di_flags);
|
||||
if (copy_to_user(arg, &flags, sizeof(flags)))
|
||||
return -XFS_ERROR(EFAULT);
|
||||
return 0;
|
||||
error = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
case XFS_IOC_SETXFLAGS: {
|
||||
if (copy_from_user(&flags, arg, sizeof(flags)))
|
||||
return -XFS_ERROR(EFAULT);
|
||||
if (copy_from_user(&flags, arg, sizeof(flags))) {
|
||||
error = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \
|
||||
LINUX_XFLAG_NOATIME | LINUX_XFLAG_NODUMP | \
|
||||
LINUX_XFLAG_SYNC))
|
||||
return -XFS_ERROR(EOPNOTSUPP);
|
||||
LINUX_XFLAG_SYNC)) {
|
||||
error = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
attr_flags = 0;
|
||||
if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
|
||||
attr_flags |= ATTR_NONBLOCK;
|
||||
|
||||
va.va_mask = XFS_AT_XFLAGS;
|
||||
va.va_xflags = xfs_merge_ioc_xflags(flags,
|
||||
xfs_ip2xflags(ip));
|
||||
vattr->va_mask = XFS_AT_XFLAGS;
|
||||
vattr->va_xflags = xfs_merge_ioc_xflags(flags,
|
||||
xfs_ip2xflags(ip));
|
||||
|
||||
VOP_SETATTR(vp, &va, attr_flags, NULL, error);
|
||||
if (!error)
|
||||
vn_revalidate(vp); /* update Linux inode flags */
|
||||
return -error;
|
||||
VOP_SETATTR(vp, vattr, attr_flags, NULL, error);
|
||||
if (likely(!error))
|
||||
__vn_revalidate(vp, vattr); /* update flags */
|
||||
error = -error;
|
||||
break;
|
||||
}
|
||||
|
||||
case XFS_IOC_GETVERSION: {
|
||||
flags = LINVFS_GET_IP(vp)->i_generation;
|
||||
flags = vn_to_inode(vp)->i_generation;
|
||||
if (copy_to_user(arg, &flags, sizeof(flags)))
|
||||
return -XFS_ERROR(EFAULT);
|
||||
return 0;
|
||||
error = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -ENOTTY;
|
||||
error = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(vattr);
|
||||
return error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
|
@ -107,11 +107,11 @@ xfs_ioctl32_bulkstat(
|
||||
#endif
|
||||
|
||||
STATIC long
|
||||
__linvfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
|
||||
xfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
|
||||
{
|
||||
int error;
|
||||
struct inode *inode = f->f_dentry->d_inode;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_to_inode(inode);
|
||||
|
||||
switch (cmd) {
|
||||
case XFS_IOC_DIOINFO:
|
||||
@ -196,19 +196,19 @@ __linvfs_compat_ioctl(int mode, struct file *f, unsigned cmd, unsigned long arg)
|
||||
}
|
||||
|
||||
long
|
||||
linvfs_compat_ioctl(
|
||||
xfs_file_compat_ioctl(
|
||||
struct file *f,
|
||||
unsigned cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return __linvfs_compat_ioctl(0, f, cmd, arg);
|
||||
return xfs_compat_ioctl(0, f, cmd, arg);
|
||||
}
|
||||
|
||||
long
|
||||
linvfs_compat_invis_ioctl(
|
||||
xfs_file_compat_invis_ioctl(
|
||||
struct file *f,
|
||||
unsigned cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
return __linvfs_compat_ioctl(IO_INVIS, f, cmd, arg);
|
||||
return xfs_compat_ioctl(IO_INVIS, f, cmd, arg);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
#ifndef __XFS_IOCTL32_H__
|
||||
#define __XFS_IOCTL32_H__
|
||||
|
||||
extern long linvfs_compat_ioctl(struct file *, unsigned, unsigned long);
|
||||
extern long linvfs_compat_invis_ioctl(struct file *f, unsigned, unsigned long);
|
||||
extern long xfs_file_compat_ioctl(struct file *, unsigned, unsigned long);
|
||||
extern long xfs_file_compat_invis_ioctl(struct file *, unsigned, unsigned long);
|
||||
|
||||
#endif /* __XFS_IOCTL32_H__ */
|
||||
|
@ -106,7 +106,7 @@ xfs_ichgtime(
|
||||
xfs_inode_t *ip,
|
||||
int flags)
|
||||
{
|
||||
struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
|
||||
struct inode *inode = vn_to_inode(XFS_ITOV(ip));
|
||||
timespec_t tv;
|
||||
|
||||
nanotime(&tv);
|
||||
@ -198,22 +198,22 @@ xfs_ichgtime_fast(
|
||||
* Pull the link count and size up from the xfs inode to the linux inode
|
||||
*/
|
||||
STATIC void
|
||||
validate_fields(
|
||||
struct inode *ip)
|
||||
xfs_validate_fields(
|
||||
struct inode *ip,
|
||||
struct vattr *vattr)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(ip);
|
||||
vattr_t va;
|
||||
vnode_t *vp = vn_from_inode(ip);
|
||||
int error;
|
||||
|
||||
va.va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
|
||||
VOP_GETATTR(vp, &va, ATTR_LAZY, NULL, error);
|
||||
if (likely(!error)) {
|
||||
ip->i_nlink = va.va_nlink;
|
||||
ip->i_blocks = va.va_nblocks;
|
||||
vattr->va_mask = XFS_AT_NLINK|XFS_AT_SIZE|XFS_AT_NBLOCKS;
|
||||
VOP_GETATTR(vp, vattr, ATTR_LAZY, NULL, error);
|
||||
if (likely(!error)) {
|
||||
ip->i_nlink = vattr->va_nlink;
|
||||
ip->i_blocks = vattr->va_nblocks;
|
||||
|
||||
/* we're under i_mutex so i_size can't change under us */
|
||||
if (i_size_read(ip) != va.va_size)
|
||||
i_size_write(ip, va.va_size);
|
||||
/* we're under i_sem so i_size can't change under us */
|
||||
if (i_size_read(ip) != vattr->va_size)
|
||||
i_size_write(ip, vattr->va_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,11 +224,11 @@ validate_fields(
|
||||
* inode, of course, such that log replay can't cause these to be lost).
|
||||
*/
|
||||
STATIC int
|
||||
linvfs_init_security(
|
||||
xfs_init_security(
|
||||
struct vnode *vp,
|
||||
struct inode *dir)
|
||||
{
|
||||
struct inode *ip = LINVFS_GET_IP(vp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
size_t length;
|
||||
void *value;
|
||||
char *name;
|
||||
@ -257,46 +257,46 @@ linvfs_init_security(
|
||||
* XXX(hch): nfsd is broken, better fix it instead.
|
||||
*/
|
||||
STATIC inline int
|
||||
has_fs_struct(struct task_struct *task)
|
||||
xfs_has_fs_struct(struct task_struct *task)
|
||||
{
|
||||
return (task->fs != init_task.fs);
|
||||
}
|
||||
|
||||
STATIC inline void
|
||||
cleanup_inode(
|
||||
xfs_cleanup_inode(
|
||||
vnode_t *dvp,
|
||||
vnode_t *vp,
|
||||
struct dentry *dentry,
|
||||
struct dentry *dentry,
|
||||
int mode)
|
||||
{
|
||||
struct dentry teardown = {};
|
||||
int err2;
|
||||
int error;
|
||||
|
||||
/* Oh, the horror.
|
||||
* If we can't add the ACL or we fail in
|
||||
* linvfs_init_security we must back out.
|
||||
* If we can't add the ACL or we fail in
|
||||
* xfs_init_security we must back out.
|
||||
* ENOSPC can hit here, among other things.
|
||||
*/
|
||||
teardown.d_inode = LINVFS_GET_IP(vp);
|
||||
teardown.d_inode = vn_to_inode(vp);
|
||||
teardown.d_name = dentry->d_name;
|
||||
|
||||
if (S_ISDIR(mode))
|
||||
VOP_RMDIR(dvp, &teardown, NULL, err2);
|
||||
VOP_RMDIR(dvp, &teardown, NULL, error);
|
||||
else
|
||||
VOP_REMOVE(dvp, &teardown, NULL, err2);
|
||||
VOP_REMOVE(dvp, &teardown, NULL, error);
|
||||
VN_RELE(vp);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_mknod(
|
||||
xfs_vn_mknod(
|
||||
struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
int mode,
|
||||
dev_t rdev)
|
||||
{
|
||||
struct inode *ip;
|
||||
vattr_t va;
|
||||
vnode_t *vp = NULL, *dvp = LINVFS_GET_VP(dir);
|
||||
vattr_t vattr = { 0 };
|
||||
vnode_t *vp = NULL, *dvp = vn_from_inode(dir);
|
||||
xfs_acl_t *default_acl = NULL;
|
||||
attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS;
|
||||
int error;
|
||||
@ -305,99 +305,98 @@ linvfs_mknod(
|
||||
* Irix uses Missed'em'V split, but doesn't want to see
|
||||
* the upper 5 bits of (14bit) major.
|
||||
*/
|
||||
if (!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff)
|
||||
if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
|
||||
return -EINVAL;
|
||||
|
||||
if (test_default_acl && test_default_acl(dvp)) {
|
||||
if (!_ACL_ALLOC(default_acl))
|
||||
if (unlikely(test_default_acl && test_default_acl(dvp))) {
|
||||
if (!_ACL_ALLOC(default_acl)) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!_ACL_GET_DEFAULT(dvp, default_acl)) {
|
||||
_ACL_FREE(default_acl);
|
||||
default_acl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_POSIXACL(dir) && !default_acl && has_fs_struct(current))
|
||||
if (IS_POSIXACL(dir) && !default_acl && xfs_has_fs_struct(current))
|
||||
mode &= ~current->fs->umask;
|
||||
|
||||
memset(&va, 0, sizeof(va));
|
||||
va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
|
||||
va.va_mode = mode;
|
||||
vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
|
||||
vattr.va_mode = mode;
|
||||
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:
|
||||
va.va_rdev = sysv_encode_dev(rdev);
|
||||
va.va_mask |= XFS_AT_RDEV;
|
||||
vattr.va_rdev = sysv_encode_dev(rdev);
|
||||
vattr.va_mask |= XFS_AT_RDEV;
|
||||
/*FALLTHROUGH*/
|
||||
case S_IFREG:
|
||||
VOP_CREATE(dvp, dentry, &va, &vp, NULL, error);
|
||||
VOP_CREATE(dvp, dentry, &vattr, &vp, NULL, error);
|
||||
break;
|
||||
case S_IFDIR:
|
||||
VOP_MKDIR(dvp, dentry, &va, &vp, NULL, error);
|
||||
VOP_MKDIR(dvp, dentry, &vattr, &vp, NULL, error);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!error)
|
||||
{
|
||||
error = linvfs_init_security(vp, dir);
|
||||
if (unlikely(!error)) {
|
||||
error = xfs_init_security(vp, dir);
|
||||
if (error)
|
||||
cleanup_inode(dvp, vp, dentry, mode);
|
||||
xfs_cleanup_inode(dvp, vp, dentry, mode);
|
||||
}
|
||||
|
||||
if (default_acl) {
|
||||
if (unlikely(default_acl)) {
|
||||
if (!error) {
|
||||
error = _ACL_INHERIT(vp, &va, default_acl);
|
||||
if (!error)
|
||||
error = _ACL_INHERIT(vp, &vattr, default_acl);
|
||||
if (!error)
|
||||
VMODIFY(vp);
|
||||
else
|
||||
cleanup_inode(dvp, vp, dentry, mode);
|
||||
xfs_cleanup_inode(dvp, vp, dentry, mode);
|
||||
}
|
||||
_ACL_FREE(default_acl);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
if (likely(!error)) {
|
||||
ASSERT(vp);
|
||||
ip = LINVFS_GET_IP(vp);
|
||||
ip = vn_to_inode(vp);
|
||||
|
||||
if (S_ISCHR(mode) || S_ISBLK(mode))
|
||||
ip->i_rdev = rdev;
|
||||
else if (S_ISDIR(mode))
|
||||
validate_fields(ip);
|
||||
xfs_validate_fields(ip, &vattr);
|
||||
d_instantiate(dentry, ip);
|
||||
validate_fields(dir);
|
||||
xfs_validate_fields(dir, &vattr);
|
||||
}
|
||||
return -error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_create(
|
||||
xfs_vn_create(
|
||||
struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
int mode,
|
||||
struct nameidata *nd)
|
||||
{
|
||||
return linvfs_mknod(dir, dentry, mode, 0);
|
||||
return xfs_vn_mknod(dir, dentry, mode, 0);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_mkdir(
|
||||
xfs_vn_mkdir(
|
||||
struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
int mode)
|
||||
{
|
||||
return linvfs_mknod(dir, dentry, mode|S_IFDIR, 0);
|
||||
return xfs_vn_mknod(dir, dentry, mode|S_IFDIR, 0);
|
||||
}
|
||||
|
||||
STATIC struct dentry *
|
||||
linvfs_lookup(
|
||||
xfs_vn_lookup(
|
||||
struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
{
|
||||
struct vnode *vp = LINVFS_GET_VP(dir), *cvp;
|
||||
struct vnode *vp = vn_from_inode(dir), *cvp;
|
||||
int error;
|
||||
|
||||
if (dentry->d_name.len >= MAXNAMELEN)
|
||||
@ -411,11 +410,11 @@ linvfs_lookup(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return d_splice_alias(LINVFS_GET_IP(cvp), dentry);
|
||||
return d_splice_alias(vn_to_inode(cvp), dentry);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_link(
|
||||
xfs_vn_link(
|
||||
struct dentry *old_dentry,
|
||||
struct inode *dir,
|
||||
struct dentry *dentry)
|
||||
@ -423,99 +422,102 @@ linvfs_link(
|
||||
struct inode *ip; /* inode of guy being linked to */
|
||||
vnode_t *tdvp; /* target directory for new name/link */
|
||||
vnode_t *vp; /* vp of name being linked */
|
||||
vattr_t vattr;
|
||||
int error;
|
||||
|
||||
ip = old_dentry->d_inode; /* inode being linked to */
|
||||
if (S_ISDIR(ip->i_mode))
|
||||
return -EPERM;
|
||||
|
||||
tdvp = LINVFS_GET_VP(dir);
|
||||
vp = LINVFS_GET_VP(ip);
|
||||
tdvp = vn_from_inode(dir);
|
||||
vp = vn_from_inode(ip);
|
||||
|
||||
VOP_LINK(tdvp, vp, dentry, NULL, error);
|
||||
if (!error) {
|
||||
if (likely(!error)) {
|
||||
VMODIFY(tdvp);
|
||||
VN_HOLD(vp);
|
||||
validate_fields(ip);
|
||||
xfs_validate_fields(ip, &vattr);
|
||||
d_instantiate(dentry, ip);
|
||||
}
|
||||
return -error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_unlink(
|
||||
xfs_vn_unlink(
|
||||
struct inode *dir,
|
||||
struct dentry *dentry)
|
||||
{
|
||||
struct inode *inode;
|
||||
vnode_t *dvp; /* directory containing name to remove */
|
||||
vattr_t vattr;
|
||||
int error;
|
||||
|
||||
inode = dentry->d_inode;
|
||||
dvp = LINVFS_GET_VP(dir);
|
||||
dvp = vn_from_inode(dir);
|
||||
|
||||
VOP_REMOVE(dvp, dentry, NULL, error);
|
||||
if (!error) {
|
||||
validate_fields(dir); /* For size only */
|
||||
validate_fields(inode);
|
||||
if (likely(!error)) {
|
||||
xfs_validate_fields(dir, &vattr); /* size needs update */
|
||||
xfs_validate_fields(inode, &vattr);
|
||||
}
|
||||
|
||||
return -error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_symlink(
|
||||
xfs_vn_symlink(
|
||||
struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
const char *symname)
|
||||
{
|
||||
struct inode *ip;
|
||||
vattr_t va;
|
||||
vattr_t vattr = { 0 };
|
||||
vnode_t *dvp; /* directory containing name of symlink */
|
||||
vnode_t *cvp; /* used to lookup symlink to put in dentry */
|
||||
int error;
|
||||
|
||||
dvp = LINVFS_GET_VP(dir);
|
||||
dvp = vn_from_inode(dir);
|
||||
cvp = NULL;
|
||||
|
||||
memset(&va, 0, sizeof(va));
|
||||
va.va_mode = S_IFLNK |
|
||||
vattr.va_mode = S_IFLNK |
|
||||
(irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO);
|
||||
va.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
|
||||
vattr.va_mask = XFS_AT_TYPE|XFS_AT_MODE;
|
||||
|
||||
error = 0;
|
||||
VOP_SYMLINK(dvp, dentry, &va, (char *)symname, &cvp, NULL, error);
|
||||
VOP_SYMLINK(dvp, dentry, &vattr, (char *)symname, &cvp, NULL, error);
|
||||
if (likely(!error && cvp)) {
|
||||
error = linvfs_init_security(cvp, dir);
|
||||
error = xfs_init_security(cvp, dir);
|
||||
if (likely(!error)) {
|
||||
ip = LINVFS_GET_IP(cvp);
|
||||
ip = vn_to_inode(cvp);
|
||||
d_instantiate(dentry, ip);
|
||||
validate_fields(dir);
|
||||
validate_fields(ip);
|
||||
xfs_validate_fields(dir, &vattr);
|
||||
xfs_validate_fields(ip, &vattr);
|
||||
} else {
|
||||
xfs_cleanup_inode(dvp, cvp, dentry, 0);
|
||||
}
|
||||
}
|
||||
return -error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_rmdir(
|
||||
xfs_vn_rmdir(
|
||||
struct inode *dir,
|
||||
struct dentry *dentry)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
vnode_t *dvp = LINVFS_GET_VP(dir);
|
||||
vnode_t *dvp = vn_from_inode(dir);
|
||||
vattr_t vattr;
|
||||
int error;
|
||||
|
||||
VOP_RMDIR(dvp, dentry, NULL, error);
|
||||
if (!error) {
|
||||
validate_fields(inode);
|
||||
validate_fields(dir);
|
||||
if (likely(!error)) {
|
||||
xfs_validate_fields(inode, &vattr);
|
||||
xfs_validate_fields(dir, &vattr);
|
||||
}
|
||||
return -error;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_rename(
|
||||
xfs_vn_rename(
|
||||
struct inode *odir,
|
||||
struct dentry *odentry,
|
||||
struct inode *ndir,
|
||||
@ -524,22 +526,21 @@ linvfs_rename(
|
||||
struct inode *new_inode = ndentry->d_inode;
|
||||
vnode_t *fvp; /* from directory */
|
||||
vnode_t *tvp; /* target directory */
|
||||
vattr_t vattr;
|
||||
int error;
|
||||
|
||||
fvp = LINVFS_GET_VP(odir);
|
||||
tvp = LINVFS_GET_VP(ndir);
|
||||
fvp = vn_from_inode(odir);
|
||||
tvp = vn_from_inode(ndir);
|
||||
|
||||
VOP_RENAME(fvp, odentry, tvp, ndentry, NULL, error);
|
||||
if (error)
|
||||
return -error;
|
||||
|
||||
if (new_inode)
|
||||
validate_fields(new_inode);
|
||||
|
||||
validate_fields(odir);
|
||||
if (ndir != odir)
|
||||
validate_fields(ndir);
|
||||
return 0;
|
||||
if (likely(!error)) {
|
||||
if (new_inode)
|
||||
xfs_validate_fields(new_inode, &vattr);
|
||||
xfs_validate_fields(odir, &vattr);
|
||||
if (ndir != odir)
|
||||
xfs_validate_fields(ndir, &vattr);
|
||||
}
|
||||
return -error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -548,7 +549,7 @@ linvfs_rename(
|
||||
* uio is kmalloced for this reason...
|
||||
*/
|
||||
STATIC void *
|
||||
linvfs_follow_link(
|
||||
xfs_vn_follow_link(
|
||||
struct dentry *dentry,
|
||||
struct nameidata *nd)
|
||||
{
|
||||
@ -574,7 +575,7 @@ linvfs_follow_link(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vp = LINVFS_GET_VP(dentry->d_inode);
|
||||
vp = vn_from_inode(dentry->d_inode);
|
||||
|
||||
iov.iov_base = link;
|
||||
iov.iov_len = MAXPATHLEN;
|
||||
@ -599,7 +600,7 @@ linvfs_follow_link(
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_put_link(
|
||||
xfs_vn_put_link(
|
||||
struct dentry *dentry,
|
||||
struct nameidata *nd,
|
||||
void *p)
|
||||
@ -612,12 +613,12 @@ linvfs_put_link(
|
||||
|
||||
#ifdef CONFIG_XFS_POSIX_ACL
|
||||
STATIC int
|
||||
linvfs_permission(
|
||||
xfs_vn_permission(
|
||||
struct inode *inode,
|
||||
int mode,
|
||||
struct nameidata *nd)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error;
|
||||
|
||||
mode <<= 6; /* convert from linux to vnode access bits */
|
||||
@ -625,17 +626,17 @@ linvfs_permission(
|
||||
return -error;
|
||||
}
|
||||
#else
|
||||
#define linvfs_permission NULL
|
||||
#define xfs_vn_permission NULL
|
||||
#endif
|
||||
|
||||
STATIC int
|
||||
linvfs_getattr(
|
||||
xfs_vn_getattr(
|
||||
struct vfsmount *mnt,
|
||||
struct dentry *dentry,
|
||||
struct kstat *stat)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error = 0;
|
||||
|
||||
if (unlikely(vp->v_flag & VMODIFIED))
|
||||
@ -646,18 +647,17 @@ linvfs_getattr(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_setattr(
|
||||
xfs_vn_setattr(
|
||||
struct dentry *dentry,
|
||||
struct iattr *attr)
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
unsigned int ia_valid = attr->ia_valid;
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vattr_t vattr;
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
vattr_t vattr = { 0 };
|
||||
int flags = 0;
|
||||
int error;
|
||||
|
||||
memset(&vattr, 0, sizeof(vattr_t));
|
||||
if (ia_valid & ATTR_UID) {
|
||||
vattr.va_mask |= XFS_AT_UID;
|
||||
vattr.va_uid = attr->ia_uid;
|
||||
@ -699,28 +699,27 @@ linvfs_setattr(
|
||||
#endif
|
||||
|
||||
VOP_SETATTR(vp, &vattr, flags, NULL, error);
|
||||
if (error)
|
||||
return -error;
|
||||
vn_revalidate(vp);
|
||||
return error;
|
||||
if (likely(!error))
|
||||
__vn_revalidate(vp, &vattr);
|
||||
return -error;
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_truncate(
|
||||
xfs_vn_truncate(
|
||||
struct inode *inode)
|
||||
{
|
||||
block_truncate_page(inode->i_mapping, inode->i_size, linvfs_get_block);
|
||||
block_truncate_page(inode->i_mapping, inode->i_size, xfs_get_block);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_setxattr(
|
||||
xfs_vn_setxattr(
|
||||
struct dentry *dentry,
|
||||
const char *name,
|
||||
const void *data,
|
||||
size_t size,
|
||||
int flags)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(dentry->d_inode);
|
||||
vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
char *attr = (char *)name;
|
||||
attrnames_t *namesp;
|
||||
int xflags = 0;
|
||||
@ -744,13 +743,13 @@ linvfs_setxattr(
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_getxattr(
|
||||
xfs_vn_getxattr(
|
||||
struct dentry *dentry,
|
||||
const char *name,
|
||||
void *data,
|
||||
size_t size)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(dentry->d_inode);
|
||||
vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
char *attr = (char *)name;
|
||||
attrnames_t *namesp;
|
||||
int xflags = 0;
|
||||
@ -774,12 +773,12 @@ linvfs_getxattr(
|
||||
}
|
||||
|
||||
STATIC ssize_t
|
||||
linvfs_listxattr(
|
||||
xfs_vn_listxattr(
|
||||
struct dentry *dentry,
|
||||
char *data,
|
||||
size_t size)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(dentry->d_inode);
|
||||
vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
int error, xflags = ATTR_KERNAMELS;
|
||||
ssize_t result;
|
||||
|
||||
@ -794,11 +793,11 @@ linvfs_listxattr(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_removexattr(
|
||||
xfs_vn_removexattr(
|
||||
struct dentry *dentry,
|
||||
const char *name)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(dentry->d_inode);
|
||||
vnode_t *vp = vn_from_inode(dentry->d_inode);
|
||||
char *attr = (char *)name;
|
||||
attrnames_t *namesp;
|
||||
int xflags = 0;
|
||||
@ -816,45 +815,45 @@ linvfs_removexattr(
|
||||
}
|
||||
|
||||
|
||||
struct inode_operations linvfs_file_inode_operations = {
|
||||
.permission = linvfs_permission,
|
||||
.truncate = linvfs_truncate,
|
||||
.getattr = linvfs_getattr,
|
||||
.setattr = linvfs_setattr,
|
||||
.setxattr = linvfs_setxattr,
|
||||
.getxattr = linvfs_getxattr,
|
||||
.listxattr = linvfs_listxattr,
|
||||
.removexattr = linvfs_removexattr,
|
||||
struct inode_operations xfs_inode_operations = {
|
||||
.permission = xfs_vn_permission,
|
||||
.truncate = xfs_vn_truncate,
|
||||
.getattr = xfs_vn_getattr,
|
||||
.setattr = xfs_vn_setattr,
|
||||
.setxattr = xfs_vn_setxattr,
|
||||
.getxattr = xfs_vn_getxattr,
|
||||
.listxattr = xfs_vn_listxattr,
|
||||
.removexattr = xfs_vn_removexattr,
|
||||
};
|
||||
|
||||
struct inode_operations linvfs_dir_inode_operations = {
|
||||
.create = linvfs_create,
|
||||
.lookup = linvfs_lookup,
|
||||
.link = linvfs_link,
|
||||
.unlink = linvfs_unlink,
|
||||
.symlink = linvfs_symlink,
|
||||
.mkdir = linvfs_mkdir,
|
||||
.rmdir = linvfs_rmdir,
|
||||
.mknod = linvfs_mknod,
|
||||
.rename = linvfs_rename,
|
||||
.permission = linvfs_permission,
|
||||
.getattr = linvfs_getattr,
|
||||
.setattr = linvfs_setattr,
|
||||
.setxattr = linvfs_setxattr,
|
||||
.getxattr = linvfs_getxattr,
|
||||
.listxattr = linvfs_listxattr,
|
||||
.removexattr = linvfs_removexattr,
|
||||
struct inode_operations xfs_dir_inode_operations = {
|
||||
.create = xfs_vn_create,
|
||||
.lookup = xfs_vn_lookup,
|
||||
.link = xfs_vn_link,
|
||||
.unlink = xfs_vn_unlink,
|
||||
.symlink = xfs_vn_symlink,
|
||||
.mkdir = xfs_vn_mkdir,
|
||||
.rmdir = xfs_vn_rmdir,
|
||||
.mknod = xfs_vn_mknod,
|
||||
.rename = xfs_vn_rename,
|
||||
.permission = xfs_vn_permission,
|
||||
.getattr = xfs_vn_getattr,
|
||||
.setattr = xfs_vn_setattr,
|
||||
.setxattr = xfs_vn_setxattr,
|
||||
.getxattr = xfs_vn_getxattr,
|
||||
.listxattr = xfs_vn_listxattr,
|
||||
.removexattr = xfs_vn_removexattr,
|
||||
};
|
||||
|
||||
struct inode_operations linvfs_symlink_inode_operations = {
|
||||
struct inode_operations xfs_symlink_inode_operations = {
|
||||
.readlink = generic_readlink,
|
||||
.follow_link = linvfs_follow_link,
|
||||
.put_link = linvfs_put_link,
|
||||
.permission = linvfs_permission,
|
||||
.getattr = linvfs_getattr,
|
||||
.setattr = linvfs_setattr,
|
||||
.setxattr = linvfs_setxattr,
|
||||
.getxattr = linvfs_getxattr,
|
||||
.listxattr = linvfs_listxattr,
|
||||
.removexattr = linvfs_removexattr,
|
||||
.follow_link = xfs_vn_follow_link,
|
||||
.put_link = xfs_vn_put_link,
|
||||
.permission = xfs_vn_permission,
|
||||
.getattr = xfs_vn_getattr,
|
||||
.setattr = xfs_vn_setattr,
|
||||
.setxattr = xfs_vn_setxattr,
|
||||
.getxattr = xfs_vn_getxattr,
|
||||
.listxattr = xfs_vn_listxattr,
|
||||
.removexattr = xfs_vn_removexattr,
|
||||
};
|
||||
|
@ -18,13 +18,13 @@
|
||||
#ifndef __XFS_IOPS_H__
|
||||
#define __XFS_IOPS_H__
|
||||
|
||||
extern struct inode_operations linvfs_file_inode_operations;
|
||||
extern struct inode_operations linvfs_dir_inode_operations;
|
||||
extern struct inode_operations linvfs_symlink_inode_operations;
|
||||
extern struct inode_operations xfs_inode_operations;
|
||||
extern struct inode_operations xfs_dir_inode_operations;
|
||||
extern struct inode_operations xfs_symlink_inode_operations;
|
||||
|
||||
extern struct file_operations linvfs_file_operations;
|
||||
extern struct file_operations linvfs_invis_file_operations;
|
||||
extern struct file_operations linvfs_dir_operations;
|
||||
extern struct file_operations xfs_file_operations;
|
||||
extern struct file_operations xfs_dir_file_operations;
|
||||
extern struct file_operations xfs_invis_file_operations;
|
||||
|
||||
extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *,
|
||||
int, unsigned int, void __user *);
|
||||
|
@ -73,6 +73,9 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/div64.h>
|
||||
@ -100,6 +103,11 @@
|
||||
*/
|
||||
#undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */
|
||||
#define HAVE_SENDFILE /* sendfile(2) exists in 2.6, but not in 2.4 */
|
||||
#ifdef CONFIG_SMP
|
||||
#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
|
||||
#else
|
||||
#undef HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* State flag for unwritten extent buffers.
|
||||
@ -226,7 +234,7 @@ BUFFER_FNS(PrivateStart, unwritten);
|
||||
#define xfs_sort(a,n,s,fn) sort(a,n,s,fn,NULL)
|
||||
#define xfs_stack_trace() dump_stack()
|
||||
#define xfs_itruncate_data(ip, off) \
|
||||
(-vmtruncate(LINVFS_GET_IP(XFS_ITOV(ip)), (off)))
|
||||
(-vmtruncate(vn_to_inode(XFS_ITOV(ip)), (off)))
|
||||
#define xfs_statvfs_fsid(statp, mp) \
|
||||
({ u64 id = huge_encode_dev((mp)->m_ddev_targp->bt_dev); \
|
||||
__kernel_fsid_t *fsid = &(statp)->f_fsid; \
|
||||
|
@ -83,7 +83,7 @@ xfs_rw_enter_trace(
|
||||
(void *)((unsigned long)ioflags),
|
||||
(void *)((unsigned long)((io->io_new_size >> 32) & 0xffffffff)),
|
||||
(void *)((unsigned long)(io->io_new_size & 0xffffffff)),
|
||||
(void *)NULL,
|
||||
(void *)((unsigned long)current_pid()),
|
||||
(void *)NULL,
|
||||
(void *)NULL,
|
||||
(void *)NULL,
|
||||
@ -113,7 +113,7 @@ xfs_inval_cached_trace(
|
||||
(void *)((unsigned long)(first & 0xffffffff)),
|
||||
(void *)((unsigned long)((last >> 32) & 0xffffffff)),
|
||||
(void *)((unsigned long)(last & 0xffffffff)),
|
||||
(void *)NULL,
|
||||
(void *)((unsigned long)current_pid()),
|
||||
(void *)NULL,
|
||||
(void *)NULL,
|
||||
(void *)NULL,
|
||||
@ -249,9 +249,8 @@ xfs_read(
|
||||
if (n < size)
|
||||
size = n;
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (unlikely(ioflags & IO_ISDIRECT))
|
||||
mutex_lock(&inode->i_mutex);
|
||||
@ -267,10 +266,14 @@ xfs_read(
|
||||
dmflags, &locktype);
|
||||
if (ret) {
|
||||
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
|
||||
goto unlock_isem;
|
||||
goto unlock_mutex;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
|
||||
VOP_FLUSHINVAL_PAGES(vp, ctooff(offtoct(*offset)),
|
||||
-1, FI_REMAPF_LOCKED);
|
||||
|
||||
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
|
||||
(void *)iovp, segs, *offset, ioflags);
|
||||
ret = __generic_file_aio_read(iocb, iovp, segs, offset);
|
||||
@ -281,7 +284,7 @@ xfs_read(
|
||||
|
||||
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
|
||||
|
||||
unlock_isem:
|
||||
unlock_mutex:
|
||||
if (unlikely(ioflags & IO_ISDIRECT))
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
return ret;
|
||||
@ -432,7 +435,7 @@ xfs_zero_eof(
|
||||
xfs_fsize_t isize, /* current inode size */
|
||||
xfs_fsize_t end_size) /* terminal inode size */
|
||||
{
|
||||
struct inode *ip = LINVFS_GET_IP(vp);
|
||||
struct inode *ip = vn_to_inode(vp);
|
||||
xfs_fileoff_t start_zero_fsb;
|
||||
xfs_fileoff_t end_zero_fsb;
|
||||
xfs_fileoff_t zero_count_fsb;
|
||||
@ -573,7 +576,7 @@ xfs_write(
|
||||
vrwlock_t locktype;
|
||||
size_t ocount = 0, count;
|
||||
loff_t pos;
|
||||
int need_isem = 1, need_flush = 0;
|
||||
int need_i_mutex = 1, need_flush = 0;
|
||||
|
||||
XFS_STATS_INC(xs_write_calls);
|
||||
|
||||
@ -622,14 +625,14 @@ xfs_write(
|
||||
return XFS_ERROR(-EINVAL);
|
||||
|
||||
if (!VN_CACHED(vp) && pos < i_size_read(inode))
|
||||
need_isem = 0;
|
||||
need_i_mutex = 0;
|
||||
|
||||
if (VN_CACHED(vp))
|
||||
need_flush = 1;
|
||||
}
|
||||
|
||||
relock:
|
||||
if (need_isem) {
|
||||
if (need_i_mutex) {
|
||||
iolock = XFS_IOLOCK_EXCL;
|
||||
locktype = VRWLOCK_WRITE;
|
||||
|
||||
@ -651,7 +654,7 @@ start:
|
||||
S_ISBLK(inode->i_mode));
|
||||
if (error) {
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
|
||||
goto out_unlock_isem;
|
||||
goto out_unlock_mutex;
|
||||
}
|
||||
|
||||
new_size = pos + count;
|
||||
@ -663,7 +666,7 @@ start:
|
||||
loff_t savedsize = pos;
|
||||
int dmflags = FILP_DELAY_FLAG(file);
|
||||
|
||||
if (need_isem)
|
||||
if (need_i_mutex)
|
||||
dmflags |= DM_FLAGS_IMUX;
|
||||
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL);
|
||||
@ -672,7 +675,7 @@ start:
|
||||
dmflags, &locktype);
|
||||
if (error) {
|
||||
xfs_iunlock(xip, iolock);
|
||||
goto out_unlock_isem;
|
||||
goto out_unlock_mutex;
|
||||
}
|
||||
xfs_ilock(xip, XFS_ILOCK_EXCL);
|
||||
eventsent = 1;
|
||||
@ -710,7 +713,7 @@ start:
|
||||
isize, pos + count);
|
||||
if (error) {
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock);
|
||||
goto out_unlock_isem;
|
||||
goto out_unlock_mutex;
|
||||
}
|
||||
}
|
||||
xfs_iunlock(xip, XFS_ILOCK_EXCL);
|
||||
@ -731,7 +734,7 @@ start:
|
||||
error = -remove_suid(file->f_dentry);
|
||||
if (unlikely(error)) {
|
||||
xfs_iunlock(xip, iolock);
|
||||
goto out_unlock_isem;
|
||||
goto out_unlock_mutex;
|
||||
}
|
||||
}
|
||||
|
||||
@ -747,14 +750,14 @@ retry:
|
||||
-1, FI_REMAPF_LOCKED);
|
||||
}
|
||||
|
||||
if (need_isem) {
|
||||
if (need_i_mutex) {
|
||||
/* demote the lock now the cached pages are gone */
|
||||
XFS_ILOCK_DEMOTE(mp, io, XFS_IOLOCK_EXCL);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
iolock = XFS_IOLOCK_SHARED;
|
||||
locktype = VRWLOCK_WRITE_DIRECT;
|
||||
need_isem = 0;
|
||||
need_i_mutex = 0;
|
||||
}
|
||||
|
||||
xfs_rw_enter_trace(XFS_DIOWR_ENTER, io, (void *)iovp, segs,
|
||||
@ -772,7 +775,7 @@ retry:
|
||||
pos += ret;
|
||||
count -= ret;
|
||||
|
||||
need_isem = 1;
|
||||
need_i_mutex = 1;
|
||||
ioflags &= ~IO_ISDIRECT;
|
||||
xfs_iunlock(xip, iolock);
|
||||
goto relock;
|
||||
@ -794,14 +797,14 @@ retry:
|
||||
!(ioflags & IO_INVIS)) {
|
||||
|
||||
xfs_rwunlock(bdp, locktype);
|
||||
if (need_isem)
|
||||
if (need_i_mutex)
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp,
|
||||
DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL,
|
||||
0, 0, 0); /* Delay flag intentionally unused */
|
||||
if (error)
|
||||
goto out_nounlocks;
|
||||
if (need_isem)
|
||||
if (need_i_mutex)
|
||||
mutex_lock(&inode->i_mutex);
|
||||
xfs_rwlock(bdp, locktype);
|
||||
pos = xip->i_d.di_size;
|
||||
@ -905,9 +908,9 @@ retry:
|
||||
if (error)
|
||||
goto out_unlock_internal;
|
||||
}
|
||||
|
||||
|
||||
xfs_rwunlock(bdp, locktype);
|
||||
if (need_isem)
|
||||
if (need_i_mutex)
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
error = sync_page_range(inode, mapping, pos, ret);
|
||||
@ -918,8 +921,8 @@ retry:
|
||||
|
||||
out_unlock_internal:
|
||||
xfs_rwunlock(bdp, locktype);
|
||||
out_unlock_isem:
|
||||
if (need_isem)
|
||||
out_unlock_mutex:
|
||||
if (need_i_mutex)
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
out_nounlocks:
|
||||
return -error;
|
||||
|
@ -59,8 +59,8 @@
|
||||
#include <linux/writeback.h>
|
||||
#include <linux/kthread.h>
|
||||
|
||||
STATIC struct quotactl_ops linvfs_qops;
|
||||
STATIC struct super_operations linvfs_sops;
|
||||
STATIC struct quotactl_ops xfs_quotactl_operations;
|
||||
STATIC struct super_operations xfs_super_operations;
|
||||
STATIC kmem_zone_t *xfs_vnode_zone;
|
||||
STATIC kmem_zone_t *xfs_ioend_zone;
|
||||
mempool_t *xfs_ioend_pool;
|
||||
@ -76,8 +76,6 @@ xfs_args_allocate(
|
||||
strncpy(args->fsname, sb->s_id, MAXNAMELEN);
|
||||
|
||||
/* Copy the already-parsed mount(2) flags we're interested in */
|
||||
if (sb->s_flags & MS_NOATIME)
|
||||
args->flags |= XFSMNT_NOATIME;
|
||||
if (sb->s_flags & MS_DIRSYNC)
|
||||
args->flags |= XFSMNT_DIRSYNC;
|
||||
if (sb->s_flags & MS_SYNCHRONOUS)
|
||||
@ -129,21 +127,21 @@ xfs_set_inodeops(
|
||||
{
|
||||
switch (inode->i_mode & S_IFMT) {
|
||||
case S_IFREG:
|
||||
inode->i_op = &linvfs_file_inode_operations;
|
||||
inode->i_fop = &linvfs_file_operations;
|
||||
inode->i_mapping->a_ops = &linvfs_aops;
|
||||
inode->i_op = &xfs_inode_operations;
|
||||
inode->i_fop = &xfs_file_operations;
|
||||
inode->i_mapping->a_ops = &xfs_address_space_operations;
|
||||
break;
|
||||
case S_IFDIR:
|
||||
inode->i_op = &linvfs_dir_inode_operations;
|
||||
inode->i_fop = &linvfs_dir_operations;
|
||||
inode->i_op = &xfs_dir_inode_operations;
|
||||
inode->i_fop = &xfs_dir_file_operations;
|
||||
break;
|
||||
case S_IFLNK:
|
||||
inode->i_op = &linvfs_symlink_inode_operations;
|
||||
inode->i_op = &xfs_symlink_inode_operations;
|
||||
if (inode->i_blocks)
|
||||
inode->i_mapping->a_ops = &linvfs_aops;
|
||||
inode->i_mapping->a_ops = &xfs_address_space_operations;
|
||||
break;
|
||||
default:
|
||||
inode->i_op = &linvfs_file_inode_operations;
|
||||
inode->i_op = &xfs_inode_operations;
|
||||
init_special_inode(inode, inode->i_mode, inode->i_rdev);
|
||||
break;
|
||||
}
|
||||
@ -155,7 +153,7 @@ xfs_revalidate_inode(
|
||||
vnode_t *vp,
|
||||
xfs_inode_t *ip)
|
||||
{
|
||||
struct inode *inode = LINVFS_GET_IP(vp);
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
||||
inode->i_mode = ip->i_d.di_mode;
|
||||
inode->i_nlink = ip->i_d.di_nlink;
|
||||
@ -212,7 +210,7 @@ xfs_initialize_vnode(
|
||||
int unlock)
|
||||
{
|
||||
xfs_inode_t *ip = XFS_BHVTOI(inode_bhv);
|
||||
struct inode *inode = LINVFS_GET_IP(vp);
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
||||
if (!inode_bhv->bd_vobj) {
|
||||
vp->v_vfsp = bhvtovfs(bdp);
|
||||
@ -230,7 +228,7 @@ xfs_initialize_vnode(
|
||||
if (ip->i_d.di_mode != 0 && unlock && (inode->i_state & I_NEW)) {
|
||||
xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
|
||||
xfs_set_inodeops(inode);
|
||||
|
||||
|
||||
ip->i_flags &= ~XFS_INEW;
|
||||
barrier();
|
||||
|
||||
@ -334,43 +332,42 @@ xfs_blkdev_issue_flush(
|
||||
}
|
||||
|
||||
STATIC struct inode *
|
||||
linvfs_alloc_inode(
|
||||
xfs_fs_alloc_inode(
|
||||
struct super_block *sb)
|
||||
{
|
||||
vnode_t *vp;
|
||||
|
||||
vp = kmem_cache_alloc(xfs_vnode_zone, kmem_flags_convert(KM_SLEEP));
|
||||
if (!vp)
|
||||
vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP);
|
||||
if (unlikely(!vp))
|
||||
return NULL;
|
||||
return LINVFS_GET_IP(vp);
|
||||
return vn_to_inode(vp);
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_destroy_inode(
|
||||
xfs_fs_destroy_inode(
|
||||
struct inode *inode)
|
||||
{
|
||||
kmem_zone_free(xfs_vnode_zone, LINVFS_GET_VP(inode));
|
||||
kmem_zone_free(xfs_vnode_zone, vn_from_inode(inode));
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_inode_init_once(
|
||||
void *data,
|
||||
kmem_cache_t *cachep,
|
||||
xfs_fs_inode_init_once(
|
||||
void *vnode,
|
||||
kmem_zone_t *zonep,
|
||||
unsigned long flags)
|
||||
{
|
||||
vnode_t *vp = (vnode_t *)data;
|
||||
|
||||
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
|
||||
SLAB_CTOR_CONSTRUCTOR)
|
||||
inode_init_once(LINVFS_GET_IP(vp));
|
||||
SLAB_CTOR_CONSTRUCTOR)
|
||||
inode_init_once(vn_to_inode((vnode_t *)vnode));
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_init_zones(void)
|
||||
xfs_init_zones(void)
|
||||
{
|
||||
xfs_vnode_zone = kmem_cache_create("xfs_vnode",
|
||||
sizeof(vnode_t), 0, SLAB_RECLAIM_ACCOUNT,
|
||||
linvfs_inode_init_once, NULL);
|
||||
xfs_vnode_zone = kmem_zone_init_flags(sizeof(vnode_t), "xfs_vnode_t",
|
||||
KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
|
||||
KM_ZONE_SPREAD,
|
||||
xfs_fs_inode_init_once);
|
||||
if (!xfs_vnode_zone)
|
||||
goto out;
|
||||
|
||||
@ -379,14 +376,12 @@ linvfs_init_zones(void)
|
||||
goto out_destroy_vnode_zone;
|
||||
|
||||
xfs_ioend_pool = mempool_create(4 * MAX_BUF_PER_PAGE,
|
||||
mempool_alloc_slab, mempool_free_slab,
|
||||
xfs_ioend_zone);
|
||||
mempool_alloc_slab, mempool_free_slab,
|
||||
xfs_ioend_zone);
|
||||
if (!xfs_ioend_pool)
|
||||
goto out_free_ioend_zone;
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
out_free_ioend_zone:
|
||||
kmem_zone_destroy(xfs_ioend_zone);
|
||||
out_destroy_vnode_zone:
|
||||
@ -396,7 +391,7 @@ linvfs_init_zones(void)
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_destroy_zones(void)
|
||||
xfs_destroy_zones(void)
|
||||
{
|
||||
mempool_destroy(xfs_ioend_pool);
|
||||
kmem_zone_destroy(xfs_vnode_zone);
|
||||
@ -407,14 +402,14 @@ linvfs_destroy_zones(void)
|
||||
* Attempt to flush the inode, this will actually fail
|
||||
* if the inode is pinned, but we dirty the inode again
|
||||
* at the point when it is unpinned after a log write,
|
||||
* since this is when the inode itself becomes flushable.
|
||||
* since this is when the inode itself becomes flushable.
|
||||
*/
|
||||
STATIC int
|
||||
linvfs_write_inode(
|
||||
xfs_fs_write_inode(
|
||||
struct inode *inode,
|
||||
int sync)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error = 0, flags = FLUSH_INODE;
|
||||
|
||||
if (vp) {
|
||||
@ -434,13 +429,13 @@ linvfs_write_inode(
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_clear_inode(
|
||||
xfs_fs_clear_inode(
|
||||
struct inode *inode)
|
||||
{
|
||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||
vnode_t *vp = vn_from_inode(inode);
|
||||
int error, cache;
|
||||
|
||||
vn_trace_entry(vp, "clear_inode", (inst_t *)__return_address);
|
||||
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
|
||||
|
||||
XFS_STATS_INC(vn_rele);
|
||||
XFS_STATS_INC(vn_remove);
|
||||
@ -516,7 +511,7 @@ void
|
||||
xfs_flush_inode(
|
||||
xfs_inode_t *ip)
|
||||
{
|
||||
struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
|
||||
struct inode *inode = vn_to_inode(XFS_ITOV(ip));
|
||||
struct vfs *vfs = XFS_MTOVFS(ip->i_mount);
|
||||
|
||||
igrab(inode);
|
||||
@ -541,7 +536,7 @@ void
|
||||
xfs_flush_device(
|
||||
xfs_inode_t *ip)
|
||||
{
|
||||
struct inode *inode = LINVFS_GET_IP(XFS_ITOV(ip));
|
||||
struct inode *inode = vn_to_inode(XFS_ITOV(ip));
|
||||
struct vfs *vfs = XFS_MTOVFS(ip->i_mount);
|
||||
|
||||
igrab(inode);
|
||||
@ -550,7 +545,7 @@ xfs_flush_device(
|
||||
xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
|
||||
}
|
||||
|
||||
#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR)
|
||||
#define SYNCD_FLAGS (SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE)
|
||||
STATIC void
|
||||
vfs_sync_worker(
|
||||
vfs_t *vfsp,
|
||||
@ -613,7 +608,7 @@ xfssyncd(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_start_syncd(
|
||||
xfs_fs_start_syncd(
|
||||
vfs_t *vfsp)
|
||||
{
|
||||
vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
|
||||
@ -625,20 +620,20 @@ linvfs_start_syncd(
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_stop_syncd(
|
||||
xfs_fs_stop_syncd(
|
||||
vfs_t *vfsp)
|
||||
{
|
||||
kthread_stop(vfsp->vfs_sync_task);
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_put_super(
|
||||
xfs_fs_put_super(
|
||||
struct super_block *sb)
|
||||
{
|
||||
vfs_t *vfsp = LINVFS_GET_VFS(sb);
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
linvfs_stop_syncd(vfsp);
|
||||
xfs_fs_stop_syncd(vfsp);
|
||||
VFS_SYNC(vfsp, SYNC_ATTR|SYNC_DELWRI, NULL, error);
|
||||
if (!error)
|
||||
VFS_UNMOUNT(vfsp, 0, NULL, error);
|
||||
@ -652,10 +647,10 @@ linvfs_put_super(
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_write_super(
|
||||
xfs_fs_write_super(
|
||||
struct super_block *sb)
|
||||
{
|
||||
vfs_t *vfsp = LINVFS_GET_VFS(sb);
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
if (sb->s_flags & MS_RDONLY) {
|
||||
@ -668,11 +663,11 @@ linvfs_write_super(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_sync_super(
|
||||
xfs_fs_sync_super(
|
||||
struct super_block *sb,
|
||||
int wait)
|
||||
{
|
||||
vfs_t *vfsp = LINVFS_GET_VFS(sb);
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
int flags = SYNC_FSDATA;
|
||||
|
||||
@ -707,11 +702,11 @@ linvfs_sync_super(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_statfs(
|
||||
xfs_fs_statfs(
|
||||
struct super_block *sb,
|
||||
struct kstatfs *statp)
|
||||
{
|
||||
vfs_t *vfsp = LINVFS_GET_VFS(sb);
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_STATVFS(vfsp, statp, NULL, error);
|
||||
@ -719,12 +714,12 @@ linvfs_statfs(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_remount(
|
||||
xfs_fs_remount(
|
||||
struct super_block *sb,
|
||||
int *flags,
|
||||
char *options)
|
||||
{
|
||||
vfs_t *vfsp = LINVFS_GET_VFS(sb);
|
||||
vfs_t *vfsp = vfs_from_sb(sb);
|
||||
struct xfs_mount_args *args = xfs_args_allocate(sb);
|
||||
int error;
|
||||
|
||||
@ -736,18 +731,18 @@ linvfs_remount(
|
||||
}
|
||||
|
||||
STATIC void
|
||||
linvfs_freeze_fs(
|
||||
xfs_fs_lockfs(
|
||||
struct super_block *sb)
|
||||
{
|
||||
VFS_FREEZE(LINVFS_GET_VFS(sb));
|
||||
VFS_FREEZE(vfs_from_sb(sb));
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_show_options(
|
||||
xfs_fs_show_options(
|
||||
struct seq_file *m,
|
||||
struct vfsmount *mnt)
|
||||
{
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(mnt->mnt_sb);
|
||||
struct vfs *vfsp = vfs_from_sb(mnt->mnt_sb);
|
||||
int error;
|
||||
|
||||
VFS_SHOWARGS(vfsp, m, error);
|
||||
@ -755,11 +750,11 @@ linvfs_show_options(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_quotasync(
|
||||
xfs_fs_quotasync(
|
||||
struct super_block *sb,
|
||||
int type)
|
||||
{
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(sb);
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_QUOTACTL(vfsp, Q_XQUOTASYNC, 0, (caddr_t)NULL, error);
|
||||
@ -767,11 +762,11 @@ linvfs_quotasync(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_getxstate(
|
||||
xfs_fs_getxstate(
|
||||
struct super_block *sb,
|
||||
struct fs_quota_stat *fqs)
|
||||
{
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(sb);
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_QUOTACTL(vfsp, Q_XGETQSTAT, 0, (caddr_t)fqs, error);
|
||||
@ -779,12 +774,12 @@ linvfs_getxstate(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_setxstate(
|
||||
xfs_fs_setxstate(
|
||||
struct super_block *sb,
|
||||
unsigned int flags,
|
||||
int op)
|
||||
{
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(sb);
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error;
|
||||
|
||||
VFS_QUOTACTL(vfsp, op, 0, (caddr_t)&flags, error);
|
||||
@ -792,13 +787,13 @@ linvfs_setxstate(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_getxquota(
|
||||
xfs_fs_getxquota(
|
||||
struct super_block *sb,
|
||||
int type,
|
||||
qid_t id,
|
||||
struct fs_disk_quota *fdq)
|
||||
{
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(sb);
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error, getmode;
|
||||
|
||||
getmode = (type == USRQUOTA) ? Q_XGETQUOTA :
|
||||
@ -808,13 +803,13 @@ linvfs_getxquota(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_setxquota(
|
||||
xfs_fs_setxquota(
|
||||
struct super_block *sb,
|
||||
int type,
|
||||
qid_t id,
|
||||
struct fs_disk_quota *fdq)
|
||||
{
|
||||
struct vfs *vfsp = LINVFS_GET_VFS(sb);
|
||||
struct vfs *vfsp = vfs_from_sb(sb);
|
||||
int error, setmode;
|
||||
|
||||
setmode = (type == USRQUOTA) ? Q_XSETQLIM :
|
||||
@ -824,21 +819,17 @@ linvfs_setxquota(
|
||||
}
|
||||
|
||||
STATIC int
|
||||
linvfs_fill_super(
|
||||
xfs_fs_fill_super(
|
||||
struct super_block *sb,
|
||||
void *data,
|
||||
int silent)
|
||||
{
|
||||
vnode_t *rootvp;
|
||||
struct vfs *vfsp = vfs_allocate();
|
||||
struct vfs *vfsp = vfs_allocate(sb);
|
||||
struct xfs_mount_args *args = xfs_args_allocate(sb);
|
||||
struct kstatfs statvfs;
|
||||
int error, error2;
|
||||
|
||||
vfsp->vfs_super = sb;
|
||||
LINVFS_SET_VFS(sb, vfsp);
|
||||
if (sb->s_flags & MS_RDONLY)
|
||||
vfsp->vfs_flag |= VFS_RDONLY;
|
||||
bhv_insert_all_vfsops(vfsp);
|
||||
|
||||
VFS_PARSEARGS(vfsp, (char *)data, args, 0, error);
|
||||
@ -849,10 +840,10 @@ linvfs_fill_super(
|
||||
|
||||
sb_min_blocksize(sb, BBSIZE);
|
||||
#ifdef CONFIG_XFS_EXPORT
|
||||
sb->s_export_op = &linvfs_export_ops;
|
||||
sb->s_export_op = &xfs_export_operations;
|
||||
#endif
|
||||
sb->s_qcop = &linvfs_qops;
|
||||
sb->s_op = &linvfs_sops;
|
||||
sb->s_qcop = &xfs_quotactl_operations;
|
||||
sb->s_op = &xfs_super_operations;
|
||||
|
||||
VFS_MOUNT(vfsp, args, NULL, error);
|
||||
if (error) {
|
||||
@ -876,7 +867,7 @@ linvfs_fill_super(
|
||||
if (error)
|
||||
goto fail_unmount;
|
||||
|
||||
sb->s_root = d_alloc_root(LINVFS_GET_IP(rootvp));
|
||||
sb->s_root = d_alloc_root(vn_to_inode(rootvp));
|
||||
if (!sb->s_root) {
|
||||
error = ENOMEM;
|
||||
goto fail_vnrele;
|
||||
@ -885,7 +876,7 @@ linvfs_fill_super(
|
||||
error = EINVAL;
|
||||
goto fail_vnrele;
|
||||
}
|
||||
if ((error = linvfs_start_syncd(vfsp)))
|
||||
if ((error = xfs_fs_start_syncd(vfsp)))
|
||||
goto fail_vnrele;
|
||||
vn_trace_exit(rootvp, __FUNCTION__, (inst_t *)__return_address);
|
||||
|
||||
@ -910,41 +901,41 @@ fail_vfsop:
|
||||
}
|
||||
|
||||
STATIC struct super_block *
|
||||
linvfs_get_sb(
|
||||
xfs_fs_get_sb(
|
||||
struct file_system_type *fs_type,
|
||||
int flags,
|
||||
const char *dev_name,
|
||||
void *data)
|
||||
{
|
||||
return get_sb_bdev(fs_type, flags, dev_name, data, linvfs_fill_super);
|
||||
return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super);
|
||||
}
|
||||
|
||||
STATIC struct super_operations linvfs_sops = {
|
||||
.alloc_inode = linvfs_alloc_inode,
|
||||
.destroy_inode = linvfs_destroy_inode,
|
||||
.write_inode = linvfs_write_inode,
|
||||
.clear_inode = linvfs_clear_inode,
|
||||
.put_super = linvfs_put_super,
|
||||
.write_super = linvfs_write_super,
|
||||
.sync_fs = linvfs_sync_super,
|
||||
.write_super_lockfs = linvfs_freeze_fs,
|
||||
.statfs = linvfs_statfs,
|
||||
.remount_fs = linvfs_remount,
|
||||
.show_options = linvfs_show_options,
|
||||
STATIC struct super_operations xfs_super_operations = {
|
||||
.alloc_inode = xfs_fs_alloc_inode,
|
||||
.destroy_inode = xfs_fs_destroy_inode,
|
||||
.write_inode = xfs_fs_write_inode,
|
||||
.clear_inode = xfs_fs_clear_inode,
|
||||
.put_super = xfs_fs_put_super,
|
||||
.write_super = xfs_fs_write_super,
|
||||
.sync_fs = xfs_fs_sync_super,
|
||||
.write_super_lockfs = xfs_fs_lockfs,
|
||||
.statfs = xfs_fs_statfs,
|
||||
.remount_fs = xfs_fs_remount,
|
||||
.show_options = xfs_fs_show_options,
|
||||
};
|
||||
|
||||
STATIC struct quotactl_ops linvfs_qops = {
|
||||
.quota_sync = linvfs_quotasync,
|
||||
.get_xstate = linvfs_getxstate,
|
||||
.set_xstate = linvfs_setxstate,
|
||||
.get_xquota = linvfs_getxquota,
|
||||
.set_xquota = linvfs_setxquota,
|
||||
STATIC struct quotactl_ops xfs_quotactl_operations = {
|
||||
.quota_sync = xfs_fs_quotasync,
|
||||
.get_xstate = xfs_fs_getxstate,
|
||||
.set_xstate = xfs_fs_setxstate,
|
||||
.get_xquota = xfs_fs_getxquota,
|
||||
.set_xquota = xfs_fs_setxquota,
|
||||
};
|
||||
|
||||
STATIC struct file_system_type xfs_fs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "xfs",
|
||||
.get_sb = linvfs_get_sb,
|
||||
.get_sb = xfs_fs_get_sb,
|
||||
.kill_sb = kill_block_super,
|
||||
.fs_flags = FS_REQUIRES_DEV,
|
||||
};
|
||||
@ -965,7 +956,7 @@ init_xfs_fs( void )
|
||||
|
||||
ktrace_init(64);
|
||||
|
||||
error = linvfs_init_zones();
|
||||
error = xfs_init_zones();
|
||||
if (error < 0)
|
||||
goto undo_zones;
|
||||
|
||||
@ -981,14 +972,13 @@ init_xfs_fs( void )
|
||||
error = register_filesystem(&xfs_fs_type);
|
||||
if (error)
|
||||
goto undo_register;
|
||||
XFS_DM_INIT(&xfs_fs_type);
|
||||
return 0;
|
||||
|
||||
undo_register:
|
||||
xfs_buf_terminate();
|
||||
|
||||
undo_buffers:
|
||||
linvfs_destroy_zones();
|
||||
xfs_destroy_zones();
|
||||
|
||||
undo_zones:
|
||||
return error;
|
||||
@ -998,11 +988,10 @@ STATIC void __exit
|
||||
exit_xfs_fs( void )
|
||||
{
|
||||
vfs_exitquota();
|
||||
XFS_DM_EXIT(&xfs_fs_type);
|
||||
unregister_filesystem(&xfs_fs_type);
|
||||
xfs_cleanup();
|
||||
xfs_buf_terminate();
|
||||
linvfs_destroy_zones();
|
||||
xfs_destroy_zones();
|
||||
ktrace_uninit();
|
||||
}
|
||||
|
||||
|
@ -98,11 +98,6 @@ extern void xfs_qm_exit(void);
|
||||
XFS_DMAPI_STRING \
|
||||
XFS_DBG_STRING /* DBG must be last */
|
||||
|
||||
#define LINVFS_GET_VFS(s) \
|
||||
(vfs_t *)((s)->s_fs_info)
|
||||
#define LINVFS_SET_VFS(s, vfsp) \
|
||||
((s)->s_fs_info = vfsp)
|
||||
|
||||
struct xfs_inode;
|
||||
struct xfs_mount;
|
||||
struct xfs_buftarg;
|
||||
@ -120,6 +115,6 @@ extern int xfs_blkdev_get(struct xfs_mount *, const char *,
|
||||
extern void xfs_blkdev_put(struct block_device *);
|
||||
extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
|
||||
|
||||
extern struct export_operations linvfs_export_ops;
|
||||
extern struct export_operations xfs_export_operations;
|
||||
|
||||
#endif /* __XFS_SUPER_H__ */
|
||||
|
@ -227,7 +227,8 @@ vfs_freeze(
|
||||
}
|
||||
|
||||
vfs_t *
|
||||
vfs_allocate( void )
|
||||
vfs_allocate(
|
||||
struct super_block *sb)
|
||||
{
|
||||
struct vfs *vfsp;
|
||||
|
||||
@ -236,9 +237,23 @@ vfs_allocate( void )
|
||||
INIT_LIST_HEAD(&vfsp->vfs_sync_list);
|
||||
spin_lock_init(&vfsp->vfs_sync_lock);
|
||||
init_waitqueue_head(&vfsp->vfs_wait_single_sync_task);
|
||||
|
||||
vfsp->vfs_super = sb;
|
||||
sb->s_fs_info = vfsp;
|
||||
|
||||
if (sb->s_flags & MS_RDONLY)
|
||||
vfsp->vfs_flag |= VFS_RDONLY;
|
||||
|
||||
return vfsp;
|
||||
}
|
||||
|
||||
vfs_t *
|
||||
vfs_from_sb(
|
||||
struct super_block *sb)
|
||||
{
|
||||
return (vfs_t *)sb->s_fs_info;
|
||||
}
|
||||
|
||||
void
|
||||
vfs_deallocate(
|
||||
struct vfs *vfsp)
|
||||
@ -295,7 +310,7 @@ bhv_remove_all_vfsops(
|
||||
bhv_remove_vfsops(vfsp, VFS_POSITION_DM);
|
||||
if (!freebase)
|
||||
return;
|
||||
mp = XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfsp), &xfs_vfsops));
|
||||
mp = XFS_VFSTOM(vfsp);
|
||||
VFS_REMOVEBHV(vfsp, &mp->m_bhv);
|
||||
xfs_mount_free(mp, 0);
|
||||
}
|
||||
|
@ -193,7 +193,8 @@ typedef struct bhv_vfsops {
|
||||
#define vfs_bhv_set_custom(b,o) ( (b)->bhv_custom = (void *)(o))
|
||||
#define vfs_bhv_clr_custom(b) ( (b)->bhv_custom = NULL )
|
||||
|
||||
extern vfs_t *vfs_allocate(void);
|
||||
extern vfs_t *vfs_allocate(struct super_block *);
|
||||
extern vfs_t *vfs_from_sb(struct super_block *);
|
||||
extern void vfs_deallocate(vfs_t *);
|
||||
extern void vfs_insertops(vfs_t *, bhv_vfsops_t *);
|
||||
extern void vfs_insertbhv(vfs_t *, bhv_desc_t *, vfsops_t *, void *);
|
||||
|
@ -58,7 +58,7 @@ struct vnode *
|
||||
vn_initialize(
|
||||
struct inode *inode)
|
||||
{
|
||||
struct vnode *vp = LINVFS_GET_VP(inode);
|
||||
struct vnode *vp = vn_from_inode(inode);
|
||||
|
||||
XFS_STATS_INC(vn_active);
|
||||
XFS_STATS_INC(vn_alloc);
|
||||
@ -83,7 +83,7 @@ vn_initialize(
|
||||
vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
|
||||
#endif /* XFS_VNODE_TRACE */
|
||||
|
||||
vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address);
|
||||
vn_trace_exit(vp, __FUNCTION__, (inst_t *)__return_address);
|
||||
return vp;
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ vn_revalidate_core(
|
||||
struct vnode *vp,
|
||||
vattr_t *vap)
|
||||
{
|
||||
struct inode *inode = LINVFS_GET_IP(vp);
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
||||
inode->i_mode = vap->va_mode;
|
||||
inode->i_nlink = vap->va_nlink;
|
||||
@ -129,24 +129,31 @@ vn_revalidate_core(
|
||||
* Revalidate the Linux inode from the vnode.
|
||||
*/
|
||||
int
|
||||
vn_revalidate(
|
||||
struct vnode *vp)
|
||||
__vn_revalidate(
|
||||
struct vnode *vp,
|
||||
struct vattr *vattr)
|
||||
{
|
||||
vattr_t va;
|
||||
int error;
|
||||
|
||||
vn_trace_entry(vp, "vn_revalidate", (inst_t *)__return_address);
|
||||
ASSERT(vp->v_fbhv != NULL);
|
||||
|
||||
va.va_mask = XFS_AT_STAT|XFS_AT_XFLAGS;
|
||||
VOP_GETATTR(vp, &va, 0, NULL, error);
|
||||
if (!error) {
|
||||
vn_revalidate_core(vp, &va);
|
||||
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
|
||||
vattr->va_mask = XFS_AT_STAT | XFS_AT_XFLAGS;
|
||||
VOP_GETATTR(vp, vattr, 0, NULL, error);
|
||||
if (likely(!error)) {
|
||||
vn_revalidate_core(vp, vattr);
|
||||
VUNMODIFY(vp);
|
||||
}
|
||||
return -error;
|
||||
}
|
||||
|
||||
int
|
||||
vn_revalidate(
|
||||
struct vnode *vp)
|
||||
{
|
||||
vattr_t vattr;
|
||||
|
||||
return __vn_revalidate(vp, &vattr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a reference to a referenced vnode.
|
||||
*/
|
||||
@ -159,7 +166,7 @@ vn_hold(
|
||||
XFS_STATS_INC(vn_hold);
|
||||
|
||||
VN_LOCK(vp);
|
||||
inode = igrab(LINVFS_GET_IP(vp));
|
||||
inode = igrab(vn_to_inode(vp));
|
||||
ASSERT(inode);
|
||||
VN_UNLOCK(vp, 0);
|
||||
|
||||
|
@ -116,8 +116,14 @@ typedef enum {
|
||||
/*
|
||||
* Vnode to Linux inode mapping.
|
||||
*/
|
||||
#define LINVFS_GET_VP(inode) ((vnode_t *)list_entry(inode, vnode_t, v_inode))
|
||||
#define LINVFS_GET_IP(vp) (&(vp)->v_inode)
|
||||
static inline struct vnode *vn_from_inode(struct inode *inode)
|
||||
{
|
||||
return (vnode_t *)list_entry(inode, vnode_t, v_inode);
|
||||
}
|
||||
static inline struct inode *vn_to_inode(struct vnode *vnode)
|
||||
{
|
||||
return &vnode->v_inode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode flags.
|
||||
@ -490,6 +496,7 @@ typedef struct vnode_map {
|
||||
(vmap).v_ino = (vp)->v_inode.i_ino; }
|
||||
|
||||
extern int vn_revalidate(struct vnode *);
|
||||
extern int __vn_revalidate(struct vnode *, vattr_t *);
|
||||
extern void vn_revalidate_core(struct vnode *, vattr_t *);
|
||||
|
||||
extern void vn_iowait(struct vnode *vp);
|
||||
@ -497,7 +504,7 @@ extern void vn_iowake(struct vnode *vp);
|
||||
|
||||
static inline int vn_count(struct vnode *vp)
|
||||
{
|
||||
return atomic_read(&LINVFS_GET_IP(vp)->i_count);
|
||||
return atomic_read(&vn_to_inode(vp)->i_count);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -511,16 +518,16 @@ extern vnode_t *vn_hold(struct vnode *);
|
||||
vn_trace_hold(vp, __FILE__, __LINE__, (inst_t *)__return_address))
|
||||
#define VN_RELE(vp) \
|
||||
(vn_trace_rele(vp, __FILE__, __LINE__, (inst_t *)__return_address), \
|
||||
iput(LINVFS_GET_IP(vp)))
|
||||
iput(vn_to_inode(vp)))
|
||||
#else
|
||||
#define VN_HOLD(vp) ((void)vn_hold(vp))
|
||||
#define VN_RELE(vp) (iput(LINVFS_GET_IP(vp)))
|
||||
#define VN_RELE(vp) (iput(vn_to_inode(vp)))
|
||||
#endif
|
||||
|
||||
static inline struct vnode *vn_grab(struct vnode *vp)
|
||||
{
|
||||
struct inode *inode = igrab(LINVFS_GET_IP(vp));
|
||||
return inode ? LINVFS_GET_VP(inode) : NULL;
|
||||
struct inode *inode = igrab(vn_to_inode(vp));
|
||||
return inode ? vn_from_inode(inode) : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -528,7 +535,7 @@ static inline struct vnode *vn_grab(struct vnode *vp)
|
||||
*/
|
||||
#define VNAME(dentry) ((char *) (dentry)->d_name.name)
|
||||
#define VNAMELEN(dentry) ((dentry)->d_name.len)
|
||||
#define VNAME_TO_VNODE(dentry) (LINVFS_GET_VP((dentry)->d_inode))
|
||||
#define VNAME_TO_VNODE(dentry) (vn_from_inode((dentry)->d_inode))
|
||||
|
||||
/*
|
||||
* Vnode spinlock manipulation.
|
||||
@ -557,12 +564,12 @@ static __inline__ void vn_flagclr(struct vnode *vp, uint flag)
|
||||
*/
|
||||
static inline void vn_mark_bad(struct vnode *vp)
|
||||
{
|
||||
make_bad_inode(LINVFS_GET_IP(vp));
|
||||
make_bad_inode(vn_to_inode(vp));
|
||||
}
|
||||
|
||||
static inline int VN_BAD(struct vnode *vp)
|
||||
{
|
||||
return is_bad_inode(LINVFS_GET_IP(vp));
|
||||
return is_bad_inode(vn_to_inode(vp));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -587,9 +594,9 @@ static inline void vn_atime_to_time_t(struct vnode *vp, time_t *tt)
|
||||
/*
|
||||
* Some useful predicates.
|
||||
*/
|
||||
#define VN_MAPPED(vp) mapping_mapped(LINVFS_GET_IP(vp)->i_mapping)
|
||||
#define VN_CACHED(vp) (LINVFS_GET_IP(vp)->i_mapping->nrpages)
|
||||
#define VN_DIRTY(vp) mapping_tagged(LINVFS_GET_IP(vp)->i_mapping, \
|
||||
#define VN_MAPPED(vp) mapping_mapped(vn_to_inode(vp)->i_mapping)
|
||||
#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages)
|
||||
#define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \
|
||||
PAGECACHE_TAG_DIRTY)
|
||||
#define VMODIFY(vp) VN_FLAGSET(vp, VMODIFIED)
|
||||
#define VUNMODIFY(vp) VN_FLAGCLR(vp, VMODIFIED)
|
||||
|
@ -79,9 +79,11 @@ xfs_qm_dquot_logitem_format(
|
||||
|
||||
logvec->i_addr = (xfs_caddr_t)&logitem->qli_format;
|
||||
logvec->i_len = sizeof(xfs_dq_logformat_t);
|
||||
XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_QFORMAT);
|
||||
logvec++;
|
||||
logvec->i_addr = (xfs_caddr_t)&logitem->qli_dquot->q_core;
|
||||
logvec->i_len = sizeof(xfs_disk_dquot_t);
|
||||
XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_DQUOT);
|
||||
|
||||
ASSERT(2 == logitem->qli_item.li_desc->lid_size);
|
||||
logitem->qli_format.qlf_size = 2;
|
||||
|
@ -1704,9 +1704,9 @@ xfs_qm_get_rtblks(
|
||||
xfs_qcnt_t *O_rtblks)
|
||||
{
|
||||
xfs_filblks_t rtblks; /* total rt blks */
|
||||
xfs_extnum_t idx; /* extent record index */
|
||||
xfs_ifork_t *ifp; /* inode fork pointer */
|
||||
xfs_extnum_t nextents; /* number of extent entries */
|
||||
xfs_bmbt_rec_t *base; /* base of extent array */
|
||||
xfs_bmbt_rec_t *ep; /* pointer to an extent entry */
|
||||
int error;
|
||||
|
||||
@ -1717,10 +1717,11 @@ xfs_qm_get_rtblks(
|
||||
return error;
|
||||
}
|
||||
rtblks = 0;
|
||||
nextents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
|
||||
base = &ifp->if_u1.if_extents[0];
|
||||
for (ep = base; ep < &base[nextents]; ep++)
|
||||
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
|
||||
for (idx = 0; idx < nextents; idx++) {
|
||||
ep = xfs_iext_get_ext(ifp, idx);
|
||||
rtblks += xfs_bmbt_get_blockcount(ep);
|
||||
}
|
||||
*O_rtblks = (xfs_qcnt_t)rtblks;
|
||||
return 0;
|
||||
}
|
||||
@ -2788,9 +2789,7 @@ xfs_qm_freelist_destroy(xfs_frlist_t *ql)
|
||||
xfs_qm_dqdestroy(dqp);
|
||||
dqp = nextdqp;
|
||||
}
|
||||
/*
|
||||
* Don't bother about unlocking.
|
||||
*/
|
||||
mutex_unlock(&ql->qh_lock);
|
||||
mutex_destroy(&ql->qh_lock);
|
||||
|
||||
ASSERT(ql->qh_nelems == 0);
|
||||
|
@ -374,7 +374,7 @@ xfs_qm_exit(void)
|
||||
vfs_bhv_clr_custom(&xfs_qmops);
|
||||
xfs_qm_cleanup_procfs();
|
||||
if (qm_dqzone)
|
||||
kmem_cache_destroy(qm_dqzone);
|
||||
kmem_zone_destroy(qm_dqzone);
|
||||
if (qm_dqtrxzone)
|
||||
kmem_cache_destroy(qm_dqtrxzone);
|
||||
kmem_zone_destroy(qm_dqtrxzone);
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ ktrace_init(int zentries)
|
||||
void
|
||||
ktrace_uninit(void)
|
||||
{
|
||||
kmem_cache_destroy(ktrace_hdr_zone);
|
||||
kmem_cache_destroy(ktrace_ent_zone);
|
||||
kmem_zone_destroy(ktrace_hdr_zone);
|
||||
kmem_zone_destroy(ktrace_ent_zone);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -21,13 +21,6 @@ static mutex_t uuid_monitor;
|
||||
static int uuid_table_size;
|
||||
static uuid_t *uuid_table;
|
||||
|
||||
void
|
||||
uuid_init(void)
|
||||
{
|
||||
mutex_init(&uuid_monitor);
|
||||
}
|
||||
|
||||
|
||||
/* IRIX interpretation of an uuid_t */
|
||||
typedef struct {
|
||||
__be32 uu_timelow;
|
||||
@ -50,7 +43,7 @@ uuid_getnodeuniq(uuid_t *uuid, int fsid [2])
|
||||
|
||||
fsid[0] = (be16_to_cpu(uup->uu_clockseq) << 16) |
|
||||
be16_to_cpu(uup->uu_timemid);
|
||||
fsid[1] = be16_to_cpu(uup->uu_timelow);
|
||||
fsid[1] = be32_to_cpu(uup->uu_timelow);
|
||||
}
|
||||
|
||||
void
|
||||
@ -139,3 +132,9 @@ uuid_table_remove(uuid_t *uuid)
|
||||
ASSERT(i < uuid_table_size);
|
||||
mutex_unlock(&uuid_monitor);
|
||||
}
|
||||
|
||||
void
|
||||
uuid_init(void)
|
||||
{
|
||||
mutex_init(&uuid_monitor);
|
||||
}
|
||||
|
@ -55,8 +55,8 @@ struct xfs_inode;
|
||||
|
||||
extern struct kmem_zone *xfs_acl_zone;
|
||||
#define xfs_acl_zone_init(zone, name) \
|
||||
(zone) = kmem_zone_init(sizeof(xfs_acl_t), name)
|
||||
#define xfs_acl_zone_destroy(zone) kmem_cache_destroy(zone)
|
||||
(zone) = kmem_zone_init(sizeof(xfs_acl_t), (name))
|
||||
#define xfs_acl_zone_destroy(zone) kmem_zone_destroy(zone)
|
||||
|
||||
extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *);
|
||||
extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
|
||||
|
@ -1127,8 +1127,7 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
|
||||
return(error);
|
||||
ASSERT(bp != NULL);
|
||||
leaf = bp->data;
|
||||
if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
|
||||
!= XFS_ATTR_LEAF_MAGIC)) {
|
||||
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);
|
||||
@ -1541,8 +1540,8 @@ xfs_attr_node_removename(xfs_da_args_t *args)
|
||||
XFS_ATTR_FORK);
|
||||
if (error)
|
||||
goto out;
|
||||
ASSERT(INT_GET(((xfs_attr_leafblock_t *)
|
||||
bp->data)->hdr.info.magic, ARCH_CONVERT)
|
||||
ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *)
|
||||
bp->data)->hdr.info.magic)
|
||||
== XFS_ATTR_LEAF_MAGIC);
|
||||
|
||||
if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
|
||||
@ -1763,7 +1762,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
||||
return(error);
|
||||
if (bp) {
|
||||
node = bp->data;
|
||||
switch (INT_GET(node->hdr.info.magic, ARCH_CONVERT)) {
|
||||
switch (be16_to_cpu(node->hdr.info.magic)) {
|
||||
case XFS_DA_NODE_MAGIC:
|
||||
xfs_attr_trace_l_cn("wrong blk", context, node);
|
||||
xfs_da_brelse(NULL, bp);
|
||||
@ -1771,18 +1770,14 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
||||
break;
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
leaf = bp->data;
|
||||
if (cursor->hashval >
|
||||
INT_GET(leaf->entries[
|
||||
INT_GET(leaf->hdr.count,
|
||||
ARCH_CONVERT)-1].hashval,
|
||||
ARCH_CONVERT)) {
|
||||
if (cursor->hashval > be32_to_cpu(leaf->entries[
|
||||
be16_to_cpu(leaf->hdr.count)-1].hashval)) {
|
||||
xfs_attr_trace_l_cl("wrong blk",
|
||||
context, leaf);
|
||||
xfs_da_brelse(NULL, bp);
|
||||
bp = NULL;
|
||||
} else if (cursor->hashval <=
|
||||
INT_GET(leaf->entries[0].hashval,
|
||||
ARCH_CONVERT)) {
|
||||
be32_to_cpu(leaf->entries[0].hashval)) {
|
||||
xfs_attr_trace_l_cl("maybe wrong blk",
|
||||
context, leaf);
|
||||
xfs_da_brelse(NULL, bp);
|
||||
@ -1817,10 +1812,10 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
||||
return(XFS_ERROR(EFSCORRUPTED));
|
||||
}
|
||||
node = bp->data;
|
||||
if (INT_GET(node->hdr.info.magic, ARCH_CONVERT)
|
||||
if (be16_to_cpu(node->hdr.info.magic)
|
||||
== XFS_ATTR_LEAF_MAGIC)
|
||||
break;
|
||||
if (unlikely(INT_GET(node->hdr.info.magic, ARCH_CONVERT)
|
||||
if (unlikely(be16_to_cpu(node->hdr.info.magic)
|
||||
!= XFS_DA_NODE_MAGIC)) {
|
||||
XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
|
||||
XFS_ERRLEVEL_LOW,
|
||||
@ -1830,19 +1825,17 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
||||
return(XFS_ERROR(EFSCORRUPTED));
|
||||
}
|
||||
btree = node->btree;
|
||||
for (i = 0;
|
||||
i < INT_GET(node->hdr.count, ARCH_CONVERT);
|
||||
for (i = 0; i < be16_to_cpu(node->hdr.count);
|
||||
btree++, i++) {
|
||||
if (cursor->hashval
|
||||
<= INT_GET(btree->hashval,
|
||||
ARCH_CONVERT)) {
|
||||
cursor->blkno = INT_GET(btree->before, ARCH_CONVERT);
|
||||
<= be32_to_cpu(btree->hashval)) {
|
||||
cursor->blkno = be32_to_cpu(btree->before);
|
||||
xfs_attr_trace_l_cb("descending",
|
||||
context, btree);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == INT_GET(node->hdr.count, ARCH_CONVERT)) {
|
||||
if (i == be16_to_cpu(node->hdr.count)) {
|
||||
xfs_da_brelse(NULL, bp);
|
||||
return(0);
|
||||
}
|
||||
@ -1858,7 +1851,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
||||
*/
|
||||
for (;;) {
|
||||
leaf = bp->data;
|
||||
if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT)
|
||||
if (unlikely(be16_to_cpu(leaf->hdr.info.magic)
|
||||
!= XFS_ATTR_LEAF_MAGIC)) {
|
||||
XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)",
|
||||
XFS_ERRLEVEL_LOW,
|
||||
@ -1869,7 +1862,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
||||
error = xfs_attr_leaf_list_int(bp, context);
|
||||
if (error || !leaf->hdr.info.forw)
|
||||
break; /* not really an error, buffer full or EOF */
|
||||
cursor->blkno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT);
|
||||
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,
|
||||
&bp, XFS_ATTR_FORK);
|
||||
@ -2232,9 +2225,10 @@ xfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context,
|
||||
: 0,
|
||||
(__psunsigned_t)context->dupcnt,
|
||||
(__psunsigned_t)context->flags,
|
||||
(__psunsigned_t)INT_GET(node->hdr.count, ARCH_CONVERT),
|
||||
(__psunsigned_t)INT_GET(node->btree[0].hashval, ARCH_CONVERT),
|
||||
(__psunsigned_t)INT_GET(node->btree[INT_GET(node->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT));
|
||||
(__psunsigned_t)be16_to_cpu(node->hdr.count),
|
||||
(__psunsigned_t)be32_to_cpu(node->btree[0].hashval),
|
||||
(__psunsigned_t)be32_to_cpu(node->btree[
|
||||
be16_to_cpu(node->hdr.count)-1].hashval));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2261,8 +2255,8 @@ xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context,
|
||||
: 0,
|
||||
(__psunsigned_t)context->dupcnt,
|
||||
(__psunsigned_t)context->flags,
|
||||
(__psunsigned_t)INT_GET(btree->hashval, ARCH_CONVERT),
|
||||
(__psunsigned_t)INT_GET(btree->before, ARCH_CONVERT),
|
||||
(__psunsigned_t)be32_to_cpu(btree->hashval),
|
||||
(__psunsigned_t)be32_to_cpu(btree->before),
|
||||
(__psunsigned_t)NULL);
|
||||
}
|
||||
|
||||
@ -2290,9 +2284,10 @@ xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context,
|
||||
: 0,
|
||||
(__psunsigned_t)context->dupcnt,
|
||||
(__psunsigned_t)context->flags,
|
||||
(__psunsigned_t)INT_GET(leaf->hdr.count, ARCH_CONVERT),
|
||||
(__psunsigned_t)INT_GET(leaf->entries[0].hashval, ARCH_CONVERT),
|
||||
(__psunsigned_t)INT_GET(leaf->entries[INT_GET(leaf->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT));
|
||||
(__psunsigned_t)be16_to_cpu(leaf->hdr.count),
|
||||
(__psunsigned_t)be32_to_cpu(leaf->entries[0].hashval),
|
||||
(__psunsigned_t)be32_to_cpu(leaf->entries[
|
||||
be16_to_cpu(leaf->hdr.count)-1].hashval));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2522,7 +2517,7 @@ attr_user_capable(
|
||||
struct vnode *vp,
|
||||
cred_t *cred)
|
||||
{
|
||||
struct inode *inode = LINVFS_GET_IP(vp);
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
return -EPERM;
|
||||
@ -2540,7 +2535,7 @@ attr_trusted_capable(
|
||||
struct vnode *vp,
|
||||
cred_t *cred)
|
||||
{
|
||||
struct inode *inode = LINVFS_GET_IP(vp);
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
return -EPERM;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -73,39 +73,39 @@ struct xfs_trans;
|
||||
#define XFS_ATTR_LEAF_MAPSIZE 3 /* how many freespace slots */
|
||||
|
||||
typedef struct xfs_attr_leaf_map { /* RLE map of free bytes */
|
||||
__uint16_t base; /* base of free region */
|
||||
__uint16_t size; /* length of free region */
|
||||
__be16 base; /* base of free region */
|
||||
__be16 size; /* length of free region */
|
||||
} xfs_attr_leaf_map_t;
|
||||
|
||||
typedef struct xfs_attr_leaf_hdr { /* constant-structure header block */
|
||||
xfs_da_blkinfo_t info; /* block type, links, etc. */
|
||||
__uint16_t count; /* count of active leaf_entry's */
|
||||
__uint16_t usedbytes; /* num bytes of names/values stored */
|
||||
__uint16_t firstused; /* first used byte in name area */
|
||||
__uint8_t holes; /* != 0 if blk needs compaction */
|
||||
__uint8_t pad1;
|
||||
__be16 count; /* count of active leaf_entry's */
|
||||
__be16 usedbytes; /* num bytes of names/values stored */
|
||||
__be16 firstused; /* first used byte in name area */
|
||||
__u8 holes; /* != 0 if blk needs compaction */
|
||||
__u8 pad1;
|
||||
xfs_attr_leaf_map_t freemap[XFS_ATTR_LEAF_MAPSIZE];
|
||||
/* N largest free regions */
|
||||
} xfs_attr_leaf_hdr_t;
|
||||
|
||||
typedef struct xfs_attr_leaf_entry { /* sorted on key, not name */
|
||||
xfs_dahash_t hashval; /* hash value of name */
|
||||
__uint16_t nameidx; /* index into buffer of name/value */
|
||||
__uint8_t flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */
|
||||
__uint8_t pad2; /* unused pad byte */
|
||||
__be32 hashval; /* hash value of name */
|
||||
__be16 nameidx; /* index into buffer of name/value */
|
||||
__u8 flags; /* LOCAL/ROOT/SECURE/INCOMPLETE flag */
|
||||
__u8 pad2; /* unused pad byte */
|
||||
} xfs_attr_leaf_entry_t;
|
||||
|
||||
typedef struct xfs_attr_leaf_name_local {
|
||||
__uint16_t valuelen; /* number of bytes in value */
|
||||
__uint8_t namelen; /* length of name bytes */
|
||||
__uint8_t nameval[1]; /* name/value bytes */
|
||||
__be16 valuelen; /* number of bytes in value */
|
||||
__u8 namelen; /* length of name bytes */
|
||||
__u8 nameval[1]; /* name/value bytes */
|
||||
} xfs_attr_leaf_name_local_t;
|
||||
|
||||
typedef struct xfs_attr_leaf_name_remote {
|
||||
xfs_dablk_t valueblk; /* block number of value bytes */
|
||||
__uint32_t valuelen; /* number of bytes in value */
|
||||
__uint8_t namelen; /* length of name bytes */
|
||||
__uint8_t name[1]; /* name bytes */
|
||||
__be32 valueblk; /* block number of value bytes */
|
||||
__be32 valuelen; /* number of bytes in value */
|
||||
__u8 namelen; /* length of name bytes */
|
||||
__u8 name[1]; /* name bytes */
|
||||
} xfs_attr_leaf_name_remote_t;
|
||||
|
||||
typedef struct xfs_attr_leafblock {
|
||||
@ -143,8 +143,8 @@ typedef struct xfs_attr_leafblock {
|
||||
static inline xfs_attr_leaf_name_remote_t *
|
||||
xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx)
|
||||
{
|
||||
return (xfs_attr_leaf_name_remote_t *) &((char *)
|
||||
(leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)];
|
||||
return (xfs_attr_leaf_name_remote_t *)
|
||||
&((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
|
||||
}
|
||||
|
||||
#define XFS_ATTR_LEAF_NAME_LOCAL(leafp,idx) \
|
||||
@ -152,16 +152,15 @@ xfs_attr_leaf_name_remote(xfs_attr_leafblock_t *leafp, int idx)
|
||||
static inline xfs_attr_leaf_name_local_t *
|
||||
xfs_attr_leaf_name_local(xfs_attr_leafblock_t *leafp, int idx)
|
||||
{
|
||||
return (xfs_attr_leaf_name_local_t *) &((char *)
|
||||
(leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)];
|
||||
return (xfs_attr_leaf_name_local_t *)
|
||||
&((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
|
||||
}
|
||||
|
||||
#define XFS_ATTR_LEAF_NAME(leafp,idx) \
|
||||
xfs_attr_leaf_name(leafp,idx)
|
||||
static inline char *xfs_attr_leaf_name(xfs_attr_leafblock_t *leafp, int idx)
|
||||
{
|
||||
return (&((char *)
|
||||
(leafp))[INT_GET((leafp)->entries[idx].nameidx, ARCH_CONVERT)]);
|
||||
return &((char *)leafp)[be16_to_cpu(leafp->entries[idx].nameidx)];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -32,8 +32,8 @@ struct xfs_inode;
|
||||
*/
|
||||
typedef struct xfs_attr_shortform {
|
||||
struct xfs_attr_sf_hdr { /* constant-structure header block */
|
||||
__uint16_t totsize; /* total bytes in shortform list */
|
||||
__uint8_t count; /* count of active entries */
|
||||
__be16 totsize; /* total bytes in shortform list */
|
||||
__u8 count; /* count of active entries */
|
||||
} hdr;
|
||||
struct xfs_attr_sf_entry {
|
||||
__uint8_t namelen; /* actual length of name (no NULL) */
|
||||
@ -66,8 +66,8 @@ typedef struct xfs_attr_sf_sort {
|
||||
#define XFS_ATTR_SF_NEXTENTRY(sfep) /* next entry in struct */ \
|
||||
((xfs_attr_sf_entry_t *)((char *)(sfep) + XFS_ATTR_SF_ENTSIZE(sfep)))
|
||||
#define XFS_ATTR_SF_TOTSIZE(dp) /* total space in use */ \
|
||||
(INT_GET(((xfs_attr_shortform_t *) \
|
||||
((dp)->i_afp->if_u1.if_data))->hdr.totsize, ARCH_CONVERT))
|
||||
(be16_to_cpu(((xfs_attr_shortform_t *) \
|
||||
((dp)->i_afp->if_u1.if_data))->hdr.totsize))
|
||||
|
||||
#if defined(XFS_ATTR_TRACE)
|
||||
/*
|
||||
|
1325
fs/xfs/xfs_bmap.c
1325
fs/xfs/xfs_bmap.c
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,7 @@
|
||||
|
||||
struct getbmap;
|
||||
struct xfs_bmbt_irec;
|
||||
struct xfs_ifork;
|
||||
struct xfs_inode;
|
||||
struct xfs_mount;
|
||||
struct xfs_trans;
|
||||
@ -347,9 +348,28 @@ xfs_bmap_count_blocks(
|
||||
*/
|
||||
int
|
||||
xfs_check_nostate_extents(
|
||||
xfs_bmbt_rec_t *ep,
|
||||
struct xfs_ifork *ifp,
|
||||
xfs_extnum_t idx,
|
||||
xfs_extnum_t num);
|
||||
|
||||
/*
|
||||
* Call xfs_bmap_do_search_extents() to search for the extent
|
||||
* record containing block bno. If in multi-level in-core extent
|
||||
* allocation mode, find and extract the target extent buffer,
|
||||
* otherwise just use the direct extent list.
|
||||
*/
|
||||
xfs_bmbt_rec_t *
|
||||
xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,
|
||||
xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
|
||||
|
||||
/*
|
||||
* Search an extent list for the extent which includes block
|
||||
* bno.
|
||||
*/
|
||||
xfs_bmbt_rec_t *xfs_bmap_do_search_extents(xfs_bmbt_rec_t *,
|
||||
xfs_extnum_t, xfs_extnum_t, xfs_fileoff_t, int *,
|
||||
xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __XFS_BMAP_H__ */
|
||||
|
@ -2754,7 +2754,7 @@ xfs_bmbt_update(
|
||||
}
|
||||
|
||||
/*
|
||||
* Check an extent list, which has just been read, for
|
||||
* Check extent records, which have just been read, for
|
||||
* any bit in the extent flag field. ASSERT on debug
|
||||
* kernels, as this condition should not occur.
|
||||
* Return an error condition (1) if any flags found,
|
||||
@ -2763,10 +2763,14 @@ xfs_bmbt_update(
|
||||
|
||||
int
|
||||
xfs_check_nostate_extents(
|
||||
xfs_bmbt_rec_t *ep,
|
||||
xfs_ifork_t *ifp,
|
||||
xfs_extnum_t idx,
|
||||
xfs_extnum_t num)
|
||||
{
|
||||
for (; num > 0; num--, ep++) {
|
||||
xfs_bmbt_rec_t *ep;
|
||||
|
||||
for (; num > 0; num--, idx++) {
|
||||
ep = xfs_iext_get_ext(ifp, idx);
|
||||
if ((ep->l0 >>
|
||||
(64 - BMBT_EXNTFLAG_BITLEN)) != 0) {
|
||||
ASSERT(0);
|
||||
|
@ -372,14 +372,6 @@ extern int xfs_bmbt_get_rec(struct xfs_btree_cur *, xfs_fileoff_t *,
|
||||
xfs_exntst_t *, int *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Search an extent list for the extent which includes block
|
||||
* bno.
|
||||
*/
|
||||
xfs_bmbt_rec_t *xfs_bmap_do_search_extents(xfs_bmbt_rec_t *,
|
||||
xfs_extnum_t, xfs_extnum_t, xfs_fileoff_t, int *,
|
||||
xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __XFS_BMAP_BTREE_H__ */
|
||||
|
@ -68,8 +68,6 @@ struct xfs_mount_args {
|
||||
* enforcement */
|
||||
#define XFSMNT_PQUOTAENF 0x00000040 /* IRIX project quota limit
|
||||
* enforcement */
|
||||
#define XFSMNT_NOATIME 0x00000100 /* don't modify access
|
||||
* times on reads */
|
||||
#define XFSMNT_NOALIGN 0x00000200 /* don't allocate at
|
||||
* stripe boundaries*/
|
||||
#define XFSMNT_RETERR 0x00000400 /* return error to user */
|
||||
|
@ -126,10 +126,10 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,
|
||||
node = bp->data;
|
||||
node->hdr.info.forw = 0;
|
||||
node->hdr.info.back = 0;
|
||||
INT_SET(node->hdr.info.magic, ARCH_CONVERT, XFS_DA_NODE_MAGIC);
|
||||
node->hdr.info.magic = cpu_to_be16(XFS_DA_NODE_MAGIC);
|
||||
node->hdr.info.pad = 0;
|
||||
node->hdr.count = 0;
|
||||
INT_SET(node->hdr.level, ARCH_CONVERT, level);
|
||||
node->hdr.level = cpu_to_be16(level);
|
||||
|
||||
xfs_da_log_buf(tp, bp,
|
||||
XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
|
||||
@ -290,28 +290,28 @@ xfs_da_split(xfs_da_state_t *state)
|
||||
|
||||
node = oldblk->bp->data;
|
||||
if (node->hdr.info.forw) {
|
||||
if (INT_GET(node->hdr.info.forw, ARCH_CONVERT) == addblk->blkno) {
|
||||
if (be32_to_cpu(node->hdr.info.forw) == addblk->blkno) {
|
||||
bp = addblk->bp;
|
||||
} else {
|
||||
ASSERT(state->extravalid);
|
||||
bp = state->extrablk.bp;
|
||||
}
|
||||
node = bp->data;
|
||||
INT_SET(node->hdr.info.back, ARCH_CONVERT, oldblk->blkno);
|
||||
node->hdr.info.back = cpu_to_be32(oldblk->blkno);
|
||||
xfs_da_log_buf(state->args->trans, bp,
|
||||
XFS_DA_LOGRANGE(node, &node->hdr.info,
|
||||
sizeof(node->hdr.info)));
|
||||
}
|
||||
node = oldblk->bp->data;
|
||||
if (INT_GET(node->hdr.info.back, ARCH_CONVERT)) {
|
||||
if (INT_GET(node->hdr.info.back, ARCH_CONVERT) == addblk->blkno) {
|
||||
if (node->hdr.info.back) {
|
||||
if (be32_to_cpu(node->hdr.info.back) == addblk->blkno) {
|
||||
bp = addblk->bp;
|
||||
} else {
|
||||
ASSERT(state->extravalid);
|
||||
bp = state->extrablk.bp;
|
||||
}
|
||||
node = bp->data;
|
||||
INT_SET(node->hdr.info.forw, ARCH_CONVERT, oldblk->blkno);
|
||||
node->hdr.info.forw = cpu_to_be32(oldblk->blkno);
|
||||
xfs_da_log_buf(state->args->trans, bp,
|
||||
XFS_DA_LOGRANGE(node, &node->hdr.info,
|
||||
sizeof(node->hdr.info)));
|
||||
@ -359,14 +359,14 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
||||
ASSERT(bp != NULL);
|
||||
node = bp->data;
|
||||
oldroot = blk1->bp->data;
|
||||
if (INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) {
|
||||
size = (int)((char *)&oldroot->btree[INT_GET(oldroot->hdr.count, ARCH_CONVERT)] -
|
||||
if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC) {
|
||||
size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] -
|
||||
(char *)oldroot);
|
||||
} else {
|
||||
ASSERT(XFS_DIR_IS_V2(mp));
|
||||
ASSERT(INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
leaf = (xfs_dir2_leaf_t *)oldroot;
|
||||
size = (int)((char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] -
|
||||
size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] -
|
||||
(char *)leaf);
|
||||
}
|
||||
memcpy(node, oldroot, size);
|
||||
@ -381,18 +381,18 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
||||
error = xfs_da_node_create(args,
|
||||
args->whichfork == XFS_DATA_FORK &&
|
||||
XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0,
|
||||
INT_GET(node->hdr.level, ARCH_CONVERT) + 1, &bp, args->whichfork);
|
||||
be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork);
|
||||
if (error)
|
||||
return(error);
|
||||
node = bp->data;
|
||||
INT_SET(node->btree[0].hashval, ARCH_CONVERT, blk1->hashval);
|
||||
INT_SET(node->btree[0].before, ARCH_CONVERT, blk1->blkno);
|
||||
INT_SET(node->btree[1].hashval, ARCH_CONVERT, blk2->hashval);
|
||||
INT_SET(node->btree[1].before, ARCH_CONVERT, blk2->blkno);
|
||||
INT_SET(node->hdr.count, ARCH_CONVERT, 2);
|
||||
node->btree[0].hashval = cpu_to_be32(blk1->hashval);
|
||||
node->btree[0].before = cpu_to_be32(blk1->blkno);
|
||||
node->btree[1].hashval = cpu_to_be32(blk2->hashval);
|
||||
node->btree[1].before = cpu_to_be32(blk2->blkno);
|
||||
node->hdr.count = cpu_to_be16(2);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
if (be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
ASSERT(blk1->blkno >= mp->m_dirleafblk &&
|
||||
blk1->blkno < mp->m_dirfreeblk);
|
||||
ASSERT(blk2->blkno >= mp->m_dirleafblk &&
|
||||
@ -424,7 +424,7 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
|
||||
int useextra;
|
||||
|
||||
node = oldblk->bp->data;
|
||||
ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
|
||||
/*
|
||||
* With V2 the extra block is data or freespace.
|
||||
@ -435,7 +435,7 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
|
||||
/*
|
||||
* Do we have to split the node?
|
||||
*/
|
||||
if ((INT_GET(node->hdr.count, ARCH_CONVERT) + newcount) > state->node_ents) {
|
||||
if ((be16_to_cpu(node->hdr.count) + newcount) > state->node_ents) {
|
||||
/*
|
||||
* Allocate a new node, add to the doubly linked chain of
|
||||
* nodes, then move some of our excess entries into it.
|
||||
@ -472,7 +472,7 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
|
||||
* If we had double-split op below us, then add the extra block too.
|
||||
*/
|
||||
node = oldblk->bp->data;
|
||||
if (oldblk->index <= INT_GET(node->hdr.count, ARCH_CONVERT)) {
|
||||
if (oldblk->index <= be16_to_cpu(node->hdr.count)) {
|
||||
oldblk->index++;
|
||||
xfs_da_node_add(state, oldblk, addblk);
|
||||
if (useextra) {
|
||||
@ -516,17 +516,17 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
||||
* Figure out how many entries need to move, and in which direction.
|
||||
* Swap the nodes around if that makes it simpler.
|
||||
*/
|
||||
if ((INT_GET(node1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(node2->hdr.count, ARCH_CONVERT) > 0) &&
|
||||
((INT_GET(node2->btree[ 0 ].hashval, ARCH_CONVERT) < INT_GET(node1->btree[ 0 ].hashval, ARCH_CONVERT)) ||
|
||||
(INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
|
||||
INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) {
|
||||
if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) &&
|
||||
((be32_to_cpu(node2->btree[0].hashval) < be32_to_cpu(node1->btree[0].hashval)) ||
|
||||
(be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) <
|
||||
be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) {
|
||||
tmpnode = node1;
|
||||
node1 = node2;
|
||||
node2 = tmpnode;
|
||||
}
|
||||
ASSERT(INT_GET(node1->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(INT_GET(node2->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
count = (INT_GET(node1->hdr.count, ARCH_CONVERT) - INT_GET(node2->hdr.count, ARCH_CONVERT)) / 2;
|
||||
ASSERT(be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
count = (be16_to_cpu(node1->hdr.count) - be16_to_cpu(node2->hdr.count)) / 2;
|
||||
if (count == 0)
|
||||
return;
|
||||
tp = state->args->trans;
|
||||
@ -537,7 +537,7 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
||||
/*
|
||||
* Move elements in node2 up to make a hole.
|
||||
*/
|
||||
if ((tmp = INT_GET(node2->hdr.count, ARCH_CONVERT)) > 0) {
|
||||
if ((tmp = be16_to_cpu(node2->hdr.count)) > 0) {
|
||||
tmp *= (uint)sizeof(xfs_da_node_entry_t);
|
||||
btree_s = &node2->btree[0];
|
||||
btree_d = &node2->btree[count];
|
||||
@ -548,13 +548,12 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
||||
* Move the req'd B-tree elements from high in node1 to
|
||||
* low in node2.
|
||||
*/
|
||||
INT_MOD(node2->hdr.count, ARCH_CONVERT, count);
|
||||
be16_add(&node2->hdr.count, count);
|
||||
tmp = count * (uint)sizeof(xfs_da_node_entry_t);
|
||||
btree_s = &node1->btree[INT_GET(node1->hdr.count, ARCH_CONVERT) - count];
|
||||
btree_s = &node1->btree[be16_to_cpu(node1->hdr.count) - count];
|
||||
btree_d = &node2->btree[0];
|
||||
memcpy(btree_d, btree_s, tmp);
|
||||
INT_MOD(node1->hdr.count, ARCH_CONVERT, -(count));
|
||||
|
||||
be16_add(&node1->hdr.count, -count);
|
||||
} else {
|
||||
/*
|
||||
* Move the req'd B-tree elements from low in node2 to
|
||||
@ -563,21 +562,21 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
||||
count = -count;
|
||||
tmp = count * (uint)sizeof(xfs_da_node_entry_t);
|
||||
btree_s = &node2->btree[0];
|
||||
btree_d = &node1->btree[INT_GET(node1->hdr.count, ARCH_CONVERT)];
|
||||
btree_d = &node1->btree[be16_to_cpu(node1->hdr.count)];
|
||||
memcpy(btree_d, btree_s, tmp);
|
||||
INT_MOD(node1->hdr.count, ARCH_CONVERT, count);
|
||||
be16_add(&node1->hdr.count, count);
|
||||
xfs_da_log_buf(tp, blk1->bp,
|
||||
XFS_DA_LOGRANGE(node1, btree_d, tmp));
|
||||
|
||||
/*
|
||||
* Move elements in node2 down to fill the hole.
|
||||
*/
|
||||
tmp = INT_GET(node2->hdr.count, ARCH_CONVERT) - count;
|
||||
tmp = be16_to_cpu(node2->hdr.count) - count;
|
||||
tmp *= (uint)sizeof(xfs_da_node_entry_t);
|
||||
btree_s = &node2->btree[count];
|
||||
btree_d = &node2->btree[0];
|
||||
memmove(btree_d, btree_s, tmp);
|
||||
INT_MOD(node2->hdr.count, ARCH_CONVERT, -(count));
|
||||
be16_add(&node2->hdr.count, -count);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -588,7 +587,7 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
||||
xfs_da_log_buf(tp, blk2->bp,
|
||||
XFS_DA_LOGRANGE(node2, &node2->hdr,
|
||||
sizeof(node2->hdr) +
|
||||
sizeof(node2->btree[0]) * INT_GET(node2->hdr.count, ARCH_CONVERT)));
|
||||
sizeof(node2->btree[0]) * be16_to_cpu(node2->hdr.count)));
|
||||
|
||||
/*
|
||||
* Record the last hashval from each block for upward propagation.
|
||||
@ -596,15 +595,15 @@ xfs_da_node_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
||||
*/
|
||||
node1 = blk1->bp->data;
|
||||
node2 = blk2->bp->data;
|
||||
blk1->hashval = INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
|
||||
blk2->hashval = INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
|
||||
blk1->hashval = be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval);
|
||||
blk2->hashval = be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval);
|
||||
|
||||
/*
|
||||
* Adjust the expected index for insertion.
|
||||
*/
|
||||
if (blk1->index >= INT_GET(node1->hdr.count, ARCH_CONVERT)) {
|
||||
blk2->index = blk1->index - INT_GET(node1->hdr.count, ARCH_CONVERT);
|
||||
blk1->index = INT_GET(node1->hdr.count, ARCH_CONVERT) + 1; /* make it invalid */
|
||||
if (blk1->index >= be16_to_cpu(node1->hdr.count)) {
|
||||
blk2->index = blk1->index - be16_to_cpu(node1->hdr.count);
|
||||
blk1->index = be16_to_cpu(node1->hdr.count) + 1; /* make it invalid */
|
||||
}
|
||||
}
|
||||
|
||||
@ -622,8 +621,8 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
|
||||
|
||||
node = oldblk->bp->data;
|
||||
mp = state->mp;
|
||||
ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT((oldblk->index >= 0) && (oldblk->index <= INT_GET(node->hdr.count, ARCH_CONVERT)));
|
||||
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count)));
|
||||
ASSERT(newblk->blkno != 0);
|
||||
if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp))
|
||||
ASSERT(newblk->blkno >= mp->m_dirleafblk &&
|
||||
@ -634,22 +633,22 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk,
|
||||
*/
|
||||
tmp = 0;
|
||||
btree = &node->btree[ oldblk->index ];
|
||||
if (oldblk->index < INT_GET(node->hdr.count, ARCH_CONVERT)) {
|
||||
tmp = (INT_GET(node->hdr.count, ARCH_CONVERT) - oldblk->index) * (uint)sizeof(*btree);
|
||||
if (oldblk->index < be16_to_cpu(node->hdr.count)) {
|
||||
tmp = (be16_to_cpu(node->hdr.count) - oldblk->index) * (uint)sizeof(*btree);
|
||||
memmove(btree + 1, btree, tmp);
|
||||
}
|
||||
INT_SET(btree->hashval, ARCH_CONVERT, newblk->hashval);
|
||||
INT_SET(btree->before, ARCH_CONVERT, newblk->blkno);
|
||||
btree->hashval = cpu_to_be32(newblk->hashval);
|
||||
btree->before = cpu_to_be32(newblk->blkno);
|
||||
xfs_da_log_buf(state->args->trans, oldblk->bp,
|
||||
XFS_DA_LOGRANGE(node, btree, tmp + sizeof(*btree)));
|
||||
INT_MOD(node->hdr.count, ARCH_CONVERT, +1);
|
||||
be16_add(&node->hdr.count, 1);
|
||||
xfs_da_log_buf(state->args->trans, oldblk->bp,
|
||||
XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
|
||||
|
||||
/*
|
||||
* Copy the last hash value from the oldblk to propagate upwards.
|
||||
*/
|
||||
oldblk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
|
||||
oldblk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1 ].hashval);
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
@ -768,21 +767,21 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
|
||||
ASSERT(args != NULL);
|
||||
ASSERT(root_blk->magic == XFS_DA_NODE_MAGIC);
|
||||
oldroot = root_blk->bp->data;
|
||||
ASSERT(INT_GET(oldroot->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(!oldroot->hdr.info.forw);
|
||||
ASSERT(!oldroot->hdr.info.back);
|
||||
|
||||
/*
|
||||
* If the root has more than one child, then don't do anything.
|
||||
*/
|
||||
if (INT_GET(oldroot->hdr.count, ARCH_CONVERT) > 1)
|
||||
if (be16_to_cpu(oldroot->hdr.count) > 1)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* Read in the (only) child block, then copy those bytes into
|
||||
* the root block's buffer and free the original child block.
|
||||
*/
|
||||
child = INT_GET(oldroot->btree[ 0 ].before, ARCH_CONVERT);
|
||||
child = be32_to_cpu(oldroot->btree[0].before);
|
||||
ASSERT(child != 0);
|
||||
error = xfs_da_read_buf(args->trans, args->dp, child, -1, &bp,
|
||||
args->whichfork);
|
||||
@ -790,11 +789,11 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
|
||||
return(error);
|
||||
ASSERT(bp != NULL);
|
||||
blkinfo = bp->data;
|
||||
if (INT_GET(oldroot->hdr.level, ARCH_CONVERT) == 1) {
|
||||
ASSERT(INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC);
|
||||
if (be16_to_cpu(oldroot->hdr.level) == 1) {
|
||||
ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC);
|
||||
} else {
|
||||
ASSERT(INT_GET(blkinfo->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC);
|
||||
}
|
||||
ASSERT(!blkinfo->forw);
|
||||
ASSERT(!blkinfo->back);
|
||||
@ -830,9 +829,9 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action)
|
||||
*/
|
||||
blk = &state->path.blk[ state->path.active-1 ];
|
||||
info = blk->bp->data;
|
||||
ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC);
|
||||
node = (xfs_da_intnode_t *)info;
|
||||
count = INT_GET(node->hdr.count, ARCH_CONVERT);
|
||||
count = be16_to_cpu(node->hdr.count);
|
||||
if (count > (state->node_ents >> 1)) {
|
||||
*action = 0; /* blk over 50%, don't try to join */
|
||||
return(0); /* blk over 50%, don't try to join */
|
||||
@ -849,7 +848,7 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action)
|
||||
* Make altpath point to the block we want to keep and
|
||||
* path point to the block we want to drop (this one).
|
||||
*/
|
||||
forward = info->forw;
|
||||
forward = (info->forw != 0);
|
||||
memcpy(&state->altpath, &state->path, sizeof(state->path));
|
||||
error = xfs_da_path_shift(state, &state->altpath, forward,
|
||||
0, &retval);
|
||||
@ -871,13 +870,12 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action)
|
||||
* to shrink a directory over time.
|
||||
*/
|
||||
/* start with smaller blk num */
|
||||
forward = (INT_GET(info->forw, ARCH_CONVERT)
|
||||
< INT_GET(info->back, ARCH_CONVERT));
|
||||
forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back));
|
||||
for (i = 0; i < 2; forward = !forward, i++) {
|
||||
if (forward)
|
||||
blkno = INT_GET(info->forw, ARCH_CONVERT);
|
||||
blkno = be32_to_cpu(info->forw);
|
||||
else
|
||||
blkno = INT_GET(info->back, ARCH_CONVERT);
|
||||
blkno = be32_to_cpu(info->back);
|
||||
if (blkno == 0)
|
||||
continue;
|
||||
error = xfs_da_read_buf(state->args->trans, state->args->dp,
|
||||
@ -889,10 +887,10 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action)
|
||||
node = (xfs_da_intnode_t *)info;
|
||||
count = state->node_ents;
|
||||
count -= state->node_ents >> 2;
|
||||
count -= INT_GET(node->hdr.count, ARCH_CONVERT);
|
||||
count -= be16_to_cpu(node->hdr.count);
|
||||
node = bp->data;
|
||||
ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
count -= INT_GET(node->hdr.count, ARCH_CONVERT);
|
||||
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
count -= be16_to_cpu(node->hdr.count);
|
||||
xfs_da_brelse(state->args->trans, bp);
|
||||
if (count >= 0)
|
||||
break; /* fits with at least 25% to spare */
|
||||
@ -973,16 +971,16 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path)
|
||||
}
|
||||
for (blk--, level--; level >= 0; blk--, level--) {
|
||||
node = blk->bp->data;
|
||||
ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
btree = &node->btree[ blk->index ];
|
||||
if (INT_GET(btree->hashval, ARCH_CONVERT) == lasthash)
|
||||
if (be32_to_cpu(btree->hashval) == lasthash)
|
||||
break;
|
||||
blk->hashval = lasthash;
|
||||
INT_SET(btree->hashval, ARCH_CONVERT, lasthash);
|
||||
btree->hashval = cpu_to_be32(lasthash);
|
||||
xfs_da_log_buf(state->args->trans, blk->bp,
|
||||
XFS_DA_LOGRANGE(node, btree, sizeof(*btree)));
|
||||
|
||||
lasthash = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
|
||||
lasthash = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,25 +995,25 @@ xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk)
|
||||
int tmp;
|
||||
|
||||
node = drop_blk->bp->data;
|
||||
ASSERT(drop_blk->index < INT_GET(node->hdr.count, ARCH_CONVERT));
|
||||
ASSERT(drop_blk->index < be16_to_cpu(node->hdr.count));
|
||||
ASSERT(drop_blk->index >= 0);
|
||||
|
||||
/*
|
||||
* Copy over the offending entry, or just zero it out.
|
||||
*/
|
||||
btree = &node->btree[drop_blk->index];
|
||||
if (drop_blk->index < (INT_GET(node->hdr.count, ARCH_CONVERT)-1)) {
|
||||
tmp = INT_GET(node->hdr.count, ARCH_CONVERT) - drop_blk->index - 1;
|
||||
if (drop_blk->index < (be16_to_cpu(node->hdr.count)-1)) {
|
||||
tmp = be16_to_cpu(node->hdr.count) - drop_blk->index - 1;
|
||||
tmp *= (uint)sizeof(xfs_da_node_entry_t);
|
||||
memmove(btree, btree + 1, tmp);
|
||||
xfs_da_log_buf(state->args->trans, drop_blk->bp,
|
||||
XFS_DA_LOGRANGE(node, btree, tmp));
|
||||
btree = &node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ];
|
||||
btree = &node->btree[be16_to_cpu(node->hdr.count)-1];
|
||||
}
|
||||
memset((char *)btree, 0, sizeof(xfs_da_node_entry_t));
|
||||
xfs_da_log_buf(state->args->trans, drop_blk->bp,
|
||||
XFS_DA_LOGRANGE(node, btree, sizeof(*btree)));
|
||||
INT_MOD(node->hdr.count, ARCH_CONVERT, -1);
|
||||
be16_add(&node->hdr.count, -1);
|
||||
xfs_da_log_buf(state->args->trans, drop_blk->bp,
|
||||
XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
|
||||
|
||||
@ -1023,7 +1021,7 @@ xfs_da_node_remove(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk)
|
||||
* Copy the last hash value from the block to propagate upwards.
|
||||
*/
|
||||
btree--;
|
||||
drop_blk->hashval = INT_GET(btree->hashval, ARCH_CONVERT);
|
||||
drop_blk->hashval = be32_to_cpu(btree->hashval);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1041,40 +1039,40 @@ xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
|
||||
|
||||
drop_node = drop_blk->bp->data;
|
||||
save_node = save_blk->bp->data;
|
||||
ASSERT(INT_GET(drop_node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(INT_GET(save_node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(drop_node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(save_node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
tp = state->args->trans;
|
||||
|
||||
/*
|
||||
* If the dying block has lower hashvals, then move all the
|
||||
* elements in the remaining block up to make a hole.
|
||||
*/
|
||||
if ((INT_GET(drop_node->btree[ 0 ].hashval, ARCH_CONVERT) < INT_GET(save_node->btree[ 0 ].hashval, ARCH_CONVERT)) ||
|
||||
(INT_GET(drop_node->btree[ INT_GET(drop_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
|
||||
INT_GET(save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))
|
||||
if ((be32_to_cpu(drop_node->btree[0].hashval) < be32_to_cpu(save_node->btree[ 0 ].hashval)) ||
|
||||
(be32_to_cpu(drop_node->btree[be16_to_cpu(drop_node->hdr.count)-1].hashval) <
|
||||
be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval)))
|
||||
{
|
||||
btree = &save_node->btree[ INT_GET(drop_node->hdr.count, ARCH_CONVERT) ];
|
||||
tmp = INT_GET(save_node->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_da_node_entry_t);
|
||||
btree = &save_node->btree[be16_to_cpu(drop_node->hdr.count)];
|
||||
tmp = be16_to_cpu(save_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t);
|
||||
memmove(btree, &save_node->btree[0], tmp);
|
||||
btree = &save_node->btree[0];
|
||||
xfs_da_log_buf(tp, save_blk->bp,
|
||||
XFS_DA_LOGRANGE(save_node, btree,
|
||||
(INT_GET(save_node->hdr.count, ARCH_CONVERT) + INT_GET(drop_node->hdr.count, ARCH_CONVERT)) *
|
||||
(be16_to_cpu(save_node->hdr.count) + be16_to_cpu(drop_node->hdr.count)) *
|
||||
sizeof(xfs_da_node_entry_t)));
|
||||
} else {
|
||||
btree = &save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT) ];
|
||||
btree = &save_node->btree[be16_to_cpu(save_node->hdr.count)];
|
||||
xfs_da_log_buf(tp, save_blk->bp,
|
||||
XFS_DA_LOGRANGE(save_node, btree,
|
||||
INT_GET(drop_node->hdr.count, ARCH_CONVERT) *
|
||||
be16_to_cpu(drop_node->hdr.count) *
|
||||
sizeof(xfs_da_node_entry_t)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Move all the B-tree elements from drop_blk to save_blk.
|
||||
*/
|
||||
tmp = INT_GET(drop_node->hdr.count, ARCH_CONVERT) * (uint)sizeof(xfs_da_node_entry_t);
|
||||
tmp = be16_to_cpu(drop_node->hdr.count) * (uint)sizeof(xfs_da_node_entry_t);
|
||||
memcpy(btree, &drop_node->btree[0], tmp);
|
||||
INT_MOD(save_node->hdr.count, ARCH_CONVERT, INT_GET(drop_node->hdr.count, ARCH_CONVERT));
|
||||
be16_add(&save_node->hdr.count, be16_to_cpu(drop_node->hdr.count));
|
||||
|
||||
xfs_da_log_buf(tp, save_blk->bp,
|
||||
XFS_DA_LOGRANGE(save_node, &save_node->hdr,
|
||||
@ -1083,7 +1081,7 @@ xfs_da_node_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
|
||||
/*
|
||||
* Save the last hashval in the remaining block for upward propagation.
|
||||
*/
|
||||
save_blk->hashval = INT_GET(save_node->btree[ INT_GET(save_node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
|
||||
save_blk->hashval = be32_to_cpu(save_node->btree[be16_to_cpu(save_node->hdr.count)-1].hashval);
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
@ -1138,46 +1136,46 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
||||
return(error);
|
||||
}
|
||||
curr = blk->bp->data;
|
||||
ASSERT(INT_GET(curr->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC ||
|
||||
INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
|
||||
be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
|
||||
|
||||
/*
|
||||
* Search an intermediate node for a match.
|
||||
*/
|
||||
blk->magic = INT_GET(curr->magic, ARCH_CONVERT);
|
||||
if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) {
|
||||
blk->magic = be16_to_cpu(curr->magic);
|
||||
if (blk->magic == XFS_DA_NODE_MAGIC) {
|
||||
node = blk->bp->data;
|
||||
blk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
|
||||
blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
|
||||
|
||||
/*
|
||||
* Binary search. (note: small blocks will skip loop)
|
||||
*/
|
||||
max = INT_GET(node->hdr.count, ARCH_CONVERT);
|
||||
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 (INT_GET(btree->hashval, ARCH_CONVERT) < hashval)
|
||||
if (be32_to_cpu(btree->hashval) < hashval)
|
||||
probe += span;
|
||||
else if (INT_GET(btree->hashval, ARCH_CONVERT) > hashval)
|
||||
else if (be32_to_cpu(btree->hashval) > hashval)
|
||||
probe -= span;
|
||||
else
|
||||
break;
|
||||
}
|
||||
ASSERT((probe >= 0) && (probe < max));
|
||||
ASSERT((span <= 4) || (INT_GET(btree->hashval, ARCH_CONVERT) == hashval));
|
||||
ASSERT((span <= 4) || (be32_to_cpu(btree->hashval) == hashval));
|
||||
|
||||
/*
|
||||
* Since we may have duplicate hashval's, find the first
|
||||
* matching hashval in the node.
|
||||
*/
|
||||
while ((probe > 0) && (INT_GET(btree->hashval, ARCH_CONVERT) >= hashval)) {
|
||||
while ((probe > 0) && (be32_to_cpu(btree->hashval) >= hashval)) {
|
||||
btree--;
|
||||
probe--;
|
||||
}
|
||||
while ((probe < max) && (INT_GET(btree->hashval, ARCH_CONVERT) < hashval)) {
|
||||
while ((probe < max) && (be32_to_cpu(btree->hashval) < hashval)) {
|
||||
btree++;
|
||||
probe++;
|
||||
}
|
||||
@ -1187,21 +1185,21 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
||||
*/
|
||||
if (probe == max) {
|
||||
blk->index = max-1;
|
||||
blkno = INT_GET(node->btree[ max-1 ].before, ARCH_CONVERT);
|
||||
blkno = be32_to_cpu(node->btree[max-1].before);
|
||||
} else {
|
||||
blk->index = probe;
|
||||
blkno = INT_GET(btree->before, ARCH_CONVERT);
|
||||
blkno = be32_to_cpu(btree->before);
|
||||
}
|
||||
}
|
||||
else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC) {
|
||||
else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
|
||||
blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
|
||||
break;
|
||||
}
|
||||
else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) {
|
||||
else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) {
|
||||
blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL);
|
||||
break;
|
||||
}
|
||||
else if (INT_GET(curr->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
|
||||
break;
|
||||
}
|
||||
@ -1274,8 +1272,8 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
|
||||
ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC ||
|
||||
old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
old_blk->magic == XFS_ATTR_LEAF_MAGIC);
|
||||
ASSERT(old_blk->magic == INT_GET(old_info->magic, ARCH_CONVERT));
|
||||
ASSERT(new_blk->magic == INT_GET(new_info->magic, ARCH_CONVERT));
|
||||
ASSERT(old_blk->magic == be16_to_cpu(old_info->magic));
|
||||
ASSERT(new_blk->magic == be16_to_cpu(new_info->magic));
|
||||
ASSERT(old_blk->magic == new_blk->magic);
|
||||
|
||||
switch (old_blk->magic) {
|
||||
@ -1302,47 +1300,44 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
|
||||
/*
|
||||
* Link new block in before existing block.
|
||||
*/
|
||||
INT_SET(new_info->forw, ARCH_CONVERT, old_blk->blkno);
|
||||
new_info->back = old_info->back; /* INT_: direct copy */
|
||||
if (INT_GET(old_info->back, ARCH_CONVERT)) {
|
||||
new_info->forw = cpu_to_be32(old_blk->blkno);
|
||||
new_info->back = old_info->back;
|
||||
if (old_info->back) {
|
||||
error = xfs_da_read_buf(args->trans, args->dp,
|
||||
INT_GET(old_info->back,
|
||||
ARCH_CONVERT), -1, &bp,
|
||||
args->whichfork);
|
||||
be32_to_cpu(old_info->back),
|
||||
-1, &bp, args->whichfork);
|
||||
if (error)
|
||||
return(error);
|
||||
ASSERT(bp != NULL);
|
||||
tmp_info = bp->data;
|
||||
ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) == INT_GET(old_info->magic, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(tmp_info->forw, ARCH_CONVERT) == old_blk->blkno);
|
||||
INT_SET(tmp_info->forw, ARCH_CONVERT, new_blk->blkno);
|
||||
ASSERT(be16_to_cpu(tmp_info->magic) == be16_to_cpu(old_info->magic));
|
||||
ASSERT(be32_to_cpu(tmp_info->forw) == old_blk->blkno);
|
||||
tmp_info->forw = cpu_to_be32(new_blk->blkno);
|
||||
xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1);
|
||||
xfs_da_buf_done(bp);
|
||||
}
|
||||
INT_SET(old_info->back, ARCH_CONVERT, new_blk->blkno);
|
||||
old_info->back = cpu_to_be32(new_blk->blkno);
|
||||
} else {
|
||||
/*
|
||||
* Link new block in after existing block.
|
||||
*/
|
||||
new_info->forw = old_info->forw; /* INT_: direct copy */
|
||||
INT_SET(new_info->back, ARCH_CONVERT, old_blk->blkno);
|
||||
if (INT_GET(old_info->forw, ARCH_CONVERT)) {
|
||||
new_info->forw = old_info->forw;
|
||||
new_info->back = cpu_to_be32(old_blk->blkno);
|
||||
if (old_info->forw) {
|
||||
error = xfs_da_read_buf(args->trans, args->dp,
|
||||
INT_GET(old_info->forw, ARCH_CONVERT), -1, &bp,
|
||||
args->whichfork);
|
||||
be32_to_cpu(old_info->forw),
|
||||
-1, &bp, args->whichfork);
|
||||
if (error)
|
||||
return(error);
|
||||
ASSERT(bp != NULL);
|
||||
tmp_info = bp->data;
|
||||
ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT)
|
||||
== INT_GET(old_info->magic, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(tmp_info->back, ARCH_CONVERT)
|
||||
== old_blk->blkno);
|
||||
INT_SET(tmp_info->back, ARCH_CONVERT, new_blk->blkno);
|
||||
ASSERT(tmp_info->magic == old_info->magic);
|
||||
ASSERT(be32_to_cpu(tmp_info->back) == old_blk->blkno);
|
||||
tmp_info->back = cpu_to_be32(new_blk->blkno);
|
||||
xfs_da_log_buf(args->trans, bp, 0, sizeof(*tmp_info)-1);
|
||||
xfs_da_buf_done(bp);
|
||||
}
|
||||
INT_SET(old_info->forw, ARCH_CONVERT, new_blk->blkno);
|
||||
old_info->forw = cpu_to_be32(new_blk->blkno);
|
||||
}
|
||||
|
||||
xfs_da_log_buf(args->trans, old_blk->bp, 0, sizeof(*tmp_info) - 1);
|
||||
@ -1360,13 +1355,13 @@ xfs_da_node_order(xfs_dabuf_t *node1_bp, xfs_dabuf_t *node2_bp)
|
||||
|
||||
node1 = node1_bp->data;
|
||||
node2 = node2_bp->data;
|
||||
ASSERT((INT_GET(node1->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) &&
|
||||
(INT_GET(node2->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC));
|
||||
if ((INT_GET(node1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(node2->hdr.count, ARCH_CONVERT) > 0) &&
|
||||
((INT_GET(node2->btree[ 0 ].hashval, ARCH_CONVERT) <
|
||||
INT_GET(node1->btree[ 0 ].hashval, ARCH_CONVERT)) ||
|
||||
(INT_GET(node2->btree[ INT_GET(node2->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT) <
|
||||
INT_GET(node1->btree[ INT_GET(node1->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT)))) {
|
||||
ASSERT((be16_to_cpu(node1->hdr.info.magic) == XFS_DA_NODE_MAGIC) &&
|
||||
(be16_to_cpu(node2->hdr.info.magic) == XFS_DA_NODE_MAGIC));
|
||||
if ((be16_to_cpu(node1->hdr.count) > 0) && (be16_to_cpu(node2->hdr.count) > 0) &&
|
||||
((be32_to_cpu(node2->btree[0].hashval) <
|
||||
be32_to_cpu(node1->btree[0].hashval)) ||
|
||||
(be32_to_cpu(node2->btree[be16_to_cpu(node2->hdr.count)-1].hashval) <
|
||||
be32_to_cpu(node1->btree[be16_to_cpu(node1->hdr.count)-1].hashval)))) {
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
@ -1381,12 +1376,12 @@ xfs_da_node_lasthash(xfs_dabuf_t *bp, int *count)
|
||||
xfs_da_intnode_t *node;
|
||||
|
||||
node = bp->data;
|
||||
ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
if (count)
|
||||
*count = INT_GET(node->hdr.count, ARCH_CONVERT);
|
||||
*count = be16_to_cpu(node->hdr.count);
|
||||
if (!node->hdr.count)
|
||||
return(0);
|
||||
return(INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT));
|
||||
return be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1411,50 +1406,47 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
|
||||
ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC ||
|
||||
save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
save_blk->magic == XFS_ATTR_LEAF_MAGIC);
|
||||
ASSERT(save_blk->magic == INT_GET(save_info->magic, ARCH_CONVERT));
|
||||
ASSERT(drop_blk->magic == INT_GET(drop_info->magic, ARCH_CONVERT));
|
||||
ASSERT(save_blk->magic == be16_to_cpu(save_info->magic));
|
||||
ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic));
|
||||
ASSERT(save_blk->magic == drop_blk->magic);
|
||||
ASSERT((INT_GET(save_info->forw, ARCH_CONVERT) == drop_blk->blkno) ||
|
||||
(INT_GET(save_info->back, ARCH_CONVERT) == drop_blk->blkno));
|
||||
ASSERT((INT_GET(drop_info->forw, ARCH_CONVERT) == save_blk->blkno) ||
|
||||
(INT_GET(drop_info->back, ARCH_CONVERT) == save_blk->blkno));
|
||||
ASSERT((be32_to_cpu(save_info->forw) == drop_blk->blkno) ||
|
||||
(be32_to_cpu(save_info->back) == drop_blk->blkno));
|
||||
ASSERT((be32_to_cpu(drop_info->forw) == save_blk->blkno) ||
|
||||
(be32_to_cpu(drop_info->back) == save_blk->blkno));
|
||||
|
||||
/*
|
||||
* Unlink the leaf block from the doubly linked chain of leaves.
|
||||
*/
|
||||
if (INT_GET(save_info->back, ARCH_CONVERT) == drop_blk->blkno) {
|
||||
save_info->back = drop_info->back; /* INT_: direct copy */
|
||||
if (INT_GET(drop_info->back, ARCH_CONVERT)) {
|
||||
if (be32_to_cpu(save_info->back) == drop_blk->blkno) {
|
||||
save_info->back = drop_info->back;
|
||||
if (drop_info->back) {
|
||||
error = xfs_da_read_buf(args->trans, args->dp,
|
||||
INT_GET(drop_info->back,
|
||||
ARCH_CONVERT), -1, &bp,
|
||||
args->whichfork);
|
||||
be32_to_cpu(drop_info->back),
|
||||
-1, &bp, args->whichfork);
|
||||
if (error)
|
||||
return(error);
|
||||
ASSERT(bp != NULL);
|
||||
tmp_info = bp->data;
|
||||
ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT) == INT_GET(save_info->magic, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(tmp_info->forw, ARCH_CONVERT) == drop_blk->blkno);
|
||||
INT_SET(tmp_info->forw, ARCH_CONVERT, save_blk->blkno);
|
||||
ASSERT(tmp_info->magic == save_info->magic);
|
||||
ASSERT(be32_to_cpu(tmp_info->forw) == drop_blk->blkno);
|
||||
tmp_info->forw = cpu_to_be32(save_blk->blkno);
|
||||
xfs_da_log_buf(args->trans, bp, 0,
|
||||
sizeof(*tmp_info) - 1);
|
||||
xfs_da_buf_done(bp);
|
||||
}
|
||||
} else {
|
||||
save_info->forw = drop_info->forw; /* INT_: direct copy */
|
||||
if (INT_GET(drop_info->forw, ARCH_CONVERT)) {
|
||||
save_info->forw = drop_info->forw;
|
||||
if (drop_info->forw) {
|
||||
error = xfs_da_read_buf(args->trans, args->dp,
|
||||
INT_GET(drop_info->forw, ARCH_CONVERT), -1, &bp,
|
||||
args->whichfork);
|
||||
be32_to_cpu(drop_info->forw),
|
||||
-1, &bp, args->whichfork);
|
||||
if (error)
|
||||
return(error);
|
||||
ASSERT(bp != NULL);
|
||||
tmp_info = bp->data;
|
||||
ASSERT(INT_GET(tmp_info->magic, ARCH_CONVERT)
|
||||
== INT_GET(save_info->magic, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(tmp_info->back, ARCH_CONVERT)
|
||||
== drop_blk->blkno);
|
||||
INT_SET(tmp_info->back, ARCH_CONVERT, save_blk->blkno);
|
||||
ASSERT(tmp_info->magic == save_info->magic);
|
||||
ASSERT(be32_to_cpu(tmp_info->back) == drop_blk->blkno);
|
||||
tmp_info->back = cpu_to_be32(save_blk->blkno);
|
||||
xfs_da_log_buf(args->trans, bp, 0,
|
||||
sizeof(*tmp_info) - 1);
|
||||
xfs_da_buf_done(bp);
|
||||
@ -1497,14 +1489,14 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
|
||||
for (blk = &path->blk[level]; level >= 0; blk--, level--) {
|
||||
ASSERT(blk->bp != NULL);
|
||||
node = blk->bp->data;
|
||||
ASSERT(INT_GET(node->hdr.info.magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
if (forward && (blk->index < INT_GET(node->hdr.count, ARCH_CONVERT)-1)) {
|
||||
ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
|
||||
if (forward && (blk->index < be16_to_cpu(node->hdr.count)-1)) {
|
||||
blk->index++;
|
||||
blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT);
|
||||
blkno = be32_to_cpu(node->btree[blk->index].before);
|
||||
break;
|
||||
} else if (!forward && (blk->index > 0)) {
|
||||
blk->index--;
|
||||
blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT);
|
||||
blkno = be32_to_cpu(node->btree[blk->index].before);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1536,18 +1528,18 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path,
|
||||
return(error);
|
||||
ASSERT(blk->bp != NULL);
|
||||
info = blk->bp->data;
|
||||
ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC ||
|
||||
INT_GET(info->magic, ARCH_CONVERT) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
INT_GET(info->magic, ARCH_CONVERT) == XFS_ATTR_LEAF_MAGIC);
|
||||
blk->magic = INT_GET(info->magic, ARCH_CONVERT);
|
||||
if (INT_GET(info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC) {
|
||||
ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC ||
|
||||
be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) ||
|
||||
be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC);
|
||||
blk->magic = be16_to_cpu(info->magic);
|
||||
if (blk->magic == XFS_DA_NODE_MAGIC) {
|
||||
node = (xfs_da_intnode_t *)info;
|
||||
blk->hashval = INT_GET(node->btree[ INT_GET(node->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT);
|
||||
blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
|
||||
if (forward)
|
||||
blk->index = 0;
|
||||
else
|
||||
blk->index = INT_GET(node->hdr.count, ARCH_CONVERT)-1;
|
||||
blkno = INT_GET(node->btree[ blk->index ].before, ARCH_CONVERT);
|
||||
blk->index = be16_to_cpu(node->hdr.count)-1;
|
||||
blkno = be32_to_cpu(node->btree[blk->index].before);
|
||||
} else {
|
||||
ASSERT(level == path->active-1);
|
||||
blk->index = 0;
|
||||
@ -1788,40 +1780,40 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
||||
/*
|
||||
* Get values from the moved block.
|
||||
*/
|
||||
if (INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) {
|
||||
if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) {
|
||||
ASSERT(XFS_DIR_IS_V1(mp));
|
||||
dead_leaf = (xfs_dir_leafblock_t *)dead_info;
|
||||
dead_level = 0;
|
||||
dead_hash =
|
||||
INT_GET(dead_leaf->entries[INT_GET(dead_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
|
||||
} else if (INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
} else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
ASSERT(XFS_DIR_IS_V2(mp));
|
||||
dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
|
||||
dead_level = 0;
|
||||
dead_hash = INT_GET(dead_leaf2->ents[INT_GET(dead_leaf2->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
|
||||
dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval);
|
||||
} else {
|
||||
ASSERT(INT_GET(dead_info->magic, ARCH_CONVERT) == XFS_DA_NODE_MAGIC);
|
||||
ASSERT(be16_to_cpu(dead_info->magic) == XFS_DA_NODE_MAGIC);
|
||||
dead_node = (xfs_da_intnode_t *)dead_info;
|
||||
dead_level = INT_GET(dead_node->hdr.level, ARCH_CONVERT);
|
||||
dead_hash = INT_GET(dead_node->btree[INT_GET(dead_node->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
|
||||
dead_level = be16_to_cpu(dead_node->hdr.level);
|
||||
dead_hash = be32_to_cpu(dead_node->btree[be16_to_cpu(dead_node->hdr.count) - 1].hashval);
|
||||
}
|
||||
sib_buf = par_buf = NULL;
|
||||
/*
|
||||
* If the moved block has a left sibling, fix up the pointers.
|
||||
*/
|
||||
if ((sib_blkno = INT_GET(dead_info->back, ARCH_CONVERT))) {
|
||||
if ((sib_blkno = be32_to_cpu(dead_info->back))) {
|
||||
if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
|
||||
goto done;
|
||||
sib_info = sib_buf->data;
|
||||
if (unlikely(
|
||||
INT_GET(sib_info->forw, ARCH_CONVERT) != last_blkno ||
|
||||
INT_GET(sib_info->magic, ARCH_CONVERT) != INT_GET(dead_info->magic, ARCH_CONVERT))) {
|
||||
be32_to_cpu(sib_info->forw) != last_blkno ||
|
||||
sib_info->magic != dead_info->magic)) {
|
||||
XFS_ERROR_REPORT("xfs_da_swap_lastblock(2)",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
error = XFS_ERROR(EFSCORRUPTED);
|
||||
goto done;
|
||||
}
|
||||
INT_SET(sib_info->forw, ARCH_CONVERT, dead_blkno);
|
||||
sib_info->forw = cpu_to_be32(dead_blkno);
|
||||
xfs_da_log_buf(tp, sib_buf,
|
||||
XFS_DA_LOGRANGE(sib_info, &sib_info->forw,
|
||||
sizeof(sib_info->forw)));
|
||||
@ -1831,20 +1823,19 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
||||
/*
|
||||
* If the moved block has a right sibling, fix up the pointers.
|
||||
*/
|
||||
if ((sib_blkno = INT_GET(dead_info->forw, ARCH_CONVERT))) {
|
||||
if ((sib_blkno = be32_to_cpu(dead_info->forw))) {
|
||||
if ((error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w)))
|
||||
goto done;
|
||||
sib_info = sib_buf->data;
|
||||
if (unlikely(
|
||||
INT_GET(sib_info->back, ARCH_CONVERT) != last_blkno
|
||||
|| INT_GET(sib_info->magic, ARCH_CONVERT)
|
||||
!= INT_GET(dead_info->magic, ARCH_CONVERT))) {
|
||||
be32_to_cpu(sib_info->back) != last_blkno ||
|
||||
sib_info->magic != dead_info->magic)) {
|
||||
XFS_ERROR_REPORT("xfs_da_swap_lastblock(3)",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
error = XFS_ERROR(EFSCORRUPTED);
|
||||
goto done;
|
||||
}
|
||||
INT_SET(sib_info->back, ARCH_CONVERT, dead_blkno);
|
||||
sib_info->back = cpu_to_be32(dead_blkno);
|
||||
xfs_da_log_buf(tp, sib_buf,
|
||||
XFS_DA_LOGRANGE(sib_info, &sib_info->back,
|
||||
sizeof(sib_info->back)));
|
||||
@ -1861,26 +1852,26 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
||||
goto done;
|
||||
par_node = par_buf->data;
|
||||
if (unlikely(
|
||||
INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC ||
|
||||
(level >= 0 && level != INT_GET(par_node->hdr.level, ARCH_CONVERT) + 1))) {
|
||||
be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC ||
|
||||
(level >= 0 && level != be16_to_cpu(par_node->hdr.level) + 1))) {
|
||||
XFS_ERROR_REPORT("xfs_da_swap_lastblock(4)",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
error = XFS_ERROR(EFSCORRUPTED);
|
||||
goto done;
|
||||
}
|
||||
level = INT_GET(par_node->hdr.level, ARCH_CONVERT);
|
||||
level = be16_to_cpu(par_node->hdr.level);
|
||||
for (entno = 0;
|
||||
entno < INT_GET(par_node->hdr.count, ARCH_CONVERT) &&
|
||||
INT_GET(par_node->btree[entno].hashval, ARCH_CONVERT) < dead_hash;
|
||||
entno < be16_to_cpu(par_node->hdr.count) &&
|
||||
be32_to_cpu(par_node->btree[entno].hashval) < dead_hash;
|
||||
entno++)
|
||||
continue;
|
||||
if (unlikely(entno == INT_GET(par_node->hdr.count, ARCH_CONVERT))) {
|
||||
if (unlikely(entno == be16_to_cpu(par_node->hdr.count))) {
|
||||
XFS_ERROR_REPORT("xfs_da_swap_lastblock(5)",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
error = XFS_ERROR(EFSCORRUPTED);
|
||||
goto done;
|
||||
}
|
||||
par_blkno = INT_GET(par_node->btree[entno].before, ARCH_CONVERT);
|
||||
par_blkno = be32_to_cpu(par_node->btree[entno].before);
|
||||
if (level == dead_level + 1)
|
||||
break;
|
||||
xfs_da_brelse(tp, par_buf);
|
||||
@ -1892,13 +1883,13 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
||||
*/
|
||||
for (;;) {
|
||||
for (;
|
||||
entno < INT_GET(par_node->hdr.count, ARCH_CONVERT) &&
|
||||
INT_GET(par_node->btree[entno].before, ARCH_CONVERT) != last_blkno;
|
||||
entno < be16_to_cpu(par_node->hdr.count) &&
|
||||
be32_to_cpu(par_node->btree[entno].before) != last_blkno;
|
||||
entno++)
|
||||
continue;
|
||||
if (entno < INT_GET(par_node->hdr.count, ARCH_CONVERT))
|
||||
if (entno < be16_to_cpu(par_node->hdr.count))
|
||||
break;
|
||||
par_blkno = INT_GET(par_node->hdr.info.forw, ARCH_CONVERT);
|
||||
par_blkno = be32_to_cpu(par_node->hdr.info.forw);
|
||||
xfs_da_brelse(tp, par_buf);
|
||||
par_buf = NULL;
|
||||
if (unlikely(par_blkno == 0)) {
|
||||
@ -1911,8 +1902,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
||||
goto done;
|
||||
par_node = par_buf->data;
|
||||
if (unlikely(
|
||||
INT_GET(par_node->hdr.level, ARCH_CONVERT) != level ||
|
||||
INT_GET(par_node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)) {
|
||||
be16_to_cpu(par_node->hdr.level) != level ||
|
||||
be16_to_cpu(par_node->hdr.info.magic) != XFS_DA_NODE_MAGIC)) {
|
||||
XFS_ERROR_REPORT("xfs_da_swap_lastblock(7)",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
error = XFS_ERROR(EFSCORRUPTED);
|
||||
@ -1923,7 +1914,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop,
|
||||
/*
|
||||
* Update the parent entry pointing to the moved block.
|
||||
*/
|
||||
INT_SET(par_node->btree[entno].before, ARCH_CONVERT, dead_blkno);
|
||||
par_node->btree[entno].before = cpu_to_be32(dead_blkno);
|
||||
xfs_da_log_buf(tp, par_buf,
|
||||
XFS_DA_LOGRANGE(par_node, &par_node->btree[entno].before,
|
||||
sizeof(par_node->btree[entno].before)));
|
||||
@ -2203,8 +2194,8 @@ xfs_da_do_buf(
|
||||
info = rbp->data;
|
||||
data = rbp->data;
|
||||
free = rbp->data;
|
||||
magic = INT_GET(info->magic, ARCH_CONVERT);
|
||||
magic1 = INT_GET(data->hdr.magic, ARCH_CONVERT);
|
||||
magic = be16_to_cpu(info->magic);
|
||||
magic1 = be32_to_cpu(data->hdr.magic);
|
||||
if (unlikely(
|
||||
XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) &&
|
||||
(magic != XFS_DIR_LEAF_MAGIC) &&
|
||||
@ -2213,7 +2204,7 @@ xfs_da_do_buf(
|
||||
(magic != XFS_DIR2_LEAFN_MAGIC) &&
|
||||
(magic1 != XFS_DIR2_BLOCK_MAGIC) &&
|
||||
(magic1 != XFS_DIR2_DATA_MAGIC) &&
|
||||
(INT_GET(free->hdr.magic, ARCH_CONVERT) != XFS_DIR2_FREE_MAGIC),
|
||||
(be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC),
|
||||
mp, XFS_ERRTAG_DA_READ_BUF,
|
||||
XFS_RANDOM_DA_READ_BUF))) {
|
||||
xfs_buftrace("DA READ ERROR", rbp->bps[0]);
|
||||
|
@ -45,10 +45,10 @@ struct zone;
|
||||
(XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC)
|
||||
|
||||
typedef struct xfs_da_blkinfo {
|
||||
xfs_dablk_t forw; /* previous block in list */
|
||||
xfs_dablk_t back; /* following block in list */
|
||||
__uint16_t magic; /* validity check on block */
|
||||
__uint16_t pad; /* unused */
|
||||
__be32 forw; /* previous block in list */
|
||||
__be32 back; /* following block in list */
|
||||
__be16 magic; /* validity check on block */
|
||||
__be16 pad; /* unused */
|
||||
} xfs_da_blkinfo_t;
|
||||
|
||||
/*
|
||||
@ -65,12 +65,12 @@ typedef struct xfs_da_blkinfo {
|
||||
typedef struct xfs_da_intnode {
|
||||
struct xfs_da_node_hdr { /* constant-structure header block */
|
||||
xfs_da_blkinfo_t info; /* block type, links, etc. */
|
||||
__uint16_t count; /* count of active entries */
|
||||
__uint16_t level; /* level above leaves (leaf == 0) */
|
||||
__be16 count; /* count of active entries */
|
||||
__be16 level; /* level above leaves (leaf == 0) */
|
||||
} hdr;
|
||||
struct xfs_da_node_entry {
|
||||
xfs_dahash_t hashval; /* hash value for this descendant */
|
||||
xfs_dablk_t before; /* Btree block before this key */
|
||||
__be32 hashval; /* hash value for this descendant */
|
||||
__be32 before; /* Btree block before this key */
|
||||
} btree[1]; /* variable sized array of keys */
|
||||
} xfs_da_intnode_t;
|
||||
typedef struct xfs_da_node_hdr xfs_da_node_hdr_t;
|
||||
|
@ -83,7 +83,7 @@ xfs_swapext(
|
||||
|
||||
/* Pull information for the target fd */
|
||||
if (((fp = fget((int)sxp->sx_fdtarget)) == NULL) ||
|
||||
((vp = LINVFS_GET_VP(fp->f_dentry->d_inode)) == NULL)) {
|
||||
((vp = vn_from_inode(fp->f_dentry->d_inode)) == NULL)) {
|
||||
error = XFS_ERROR(EINVAL);
|
||||
goto error0;
|
||||
}
|
||||
@ -95,7 +95,7 @@ xfs_swapext(
|
||||
}
|
||||
|
||||
if (((tfp = fget((int)sxp->sx_fdtmp)) == NULL) ||
|
||||
((tvp = LINVFS_GET_VP(tfp->f_dentry->d_inode)) == NULL)) {
|
||||
((tvp = vn_from_inode(tfp->f_dentry->d_inode)) == NULL)) {
|
||||
error = XFS_ERROR(EINVAL);
|
||||
goto error0;
|
||||
}
|
||||
|
@ -634,7 +634,7 @@ xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen)
|
||||
return(retval);
|
||||
ASSERT(bp != NULL);
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
retval = xfs_dir_leaf_lookup_int(bp, args, &index);
|
||||
if (retval == EEXIST) {
|
||||
(void)xfs_dir_leaf_remove(args->trans, bp, index);
|
||||
@ -912,7 +912,7 @@ xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
|
||||
return(error);
|
||||
if (bp)
|
||||
leaf = bp->data;
|
||||
if (bp && INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) {
|
||||
if (bp && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
|
||||
xfs_dir_trace_g_dub("node: block not a leaf",
|
||||
dp, uio, bno);
|
||||
xfs_da_brelse(trans, bp);
|
||||
@ -949,17 +949,17 @@ xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
|
||||
if (bp == NULL)
|
||||
return(XFS_ERROR(EFSCORRUPTED));
|
||||
node = bp->data;
|
||||
if (INT_GET(node->hdr.info.magic, ARCH_CONVERT) != XFS_DA_NODE_MAGIC)
|
||||
if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC)
|
||||
break;
|
||||
btree = &node->btree[0];
|
||||
xfs_dir_trace_g_dun("node: node detail", dp, uio, node);
|
||||
for (i = 0; i < INT_GET(node->hdr.count, ARCH_CONVERT); btree++, i++) {
|
||||
if (INT_GET(btree->hashval, ARCH_CONVERT) >= cookhash) {
|
||||
bno = INT_GET(btree->before, ARCH_CONVERT);
|
||||
for (i = 0; i < be16_to_cpu(node->hdr.count); btree++, i++) {
|
||||
if (be32_to_cpu(btree->hashval) >= cookhash) {
|
||||
bno = be32_to_cpu(btree->before);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == INT_GET(node->hdr.count, ARCH_CONVERT)) {
|
||||
if (i == be16_to_cpu(node->hdr.count)) {
|
||||
xfs_da_brelse(trans, bp);
|
||||
xfs_dir_trace_g_du("node: hash beyond EOF",
|
||||
dp, uio);
|
||||
@ -982,7 +982,7 @@ xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
|
||||
*/
|
||||
for (;;) {
|
||||
leaf = bp->data;
|
||||
if (unlikely(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC)) {
|
||||
if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC)) {
|
||||
xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf);
|
||||
xfs_da_brelse(trans, bp);
|
||||
XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)",
|
||||
@ -990,7 +990,7 @@ xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio,
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf);
|
||||
if ((nextbno = INT_GET(leaf->hdr.info.forw, ARCH_CONVERT))) {
|
||||
if ((nextbno = be32_to_cpu(leaf->hdr.info.forw))) {
|
||||
nextda = xfs_da_reada_buf(trans, dp, nextbno,
|
||||
XFS_DATA_FORK);
|
||||
} else
|
||||
@ -1118,21 +1118,20 @@ void
|
||||
xfs_dir_trace_g_dun(char *where, xfs_inode_t *dp, uio_t *uio,
|
||||
xfs_da_intnode_t *node)
|
||||
{
|
||||
int last = INT_GET(node->hdr.count, ARCH_CONVERT) - 1;
|
||||
int last = be16_to_cpu(node->hdr.count) - 1;
|
||||
|
||||
xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUN, where,
|
||||
(void *)dp, (void *)dp->i_mount,
|
||||
(void *)((unsigned long)(uio->uio_offset >> 32)),
|
||||
(void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
|
||||
(void *)(unsigned long)uio->uio_resid,
|
||||
(void *)(unsigned long)be32_to_cpu(node->hdr.info.forw),
|
||||
(void *)(unsigned long)
|
||||
INT_GET(node->hdr.info.forw, ARCH_CONVERT),
|
||||
be16_to_cpu(node->hdr.count),
|
||||
(void *)(unsigned long)
|
||||
INT_GET(node->hdr.count, ARCH_CONVERT),
|
||||
be32_to_cpu(node->btree[0].hashval),
|
||||
(void *)(unsigned long)
|
||||
INT_GET(node->btree[0].hashval, ARCH_CONVERT),
|
||||
(void *)(unsigned long)
|
||||
INT_GET(node->btree[last].hashval, ARCH_CONVERT),
|
||||
be32_to_cpu(node->btree[last].hashval),
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
@ -1150,8 +1149,7 @@ xfs_dir_trace_g_dul(char *where, xfs_inode_t *dp, uio_t *uio,
|
||||
(void *)((unsigned long)(uio->uio_offset >> 32)),
|
||||
(void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)),
|
||||
(void *)(unsigned long)uio->uio_resid,
|
||||
(void *)(unsigned long)
|
||||
INT_GET(leaf->hdr.info.forw, ARCH_CONVERT),
|
||||
(void *)(unsigned long)be32_to_cpu(leaf->hdr.info.forw),
|
||||
(void *)(unsigned long)
|
||||
INT_GET(leaf->hdr.count, ARCH_CONVERT),
|
||||
(void *)(unsigned long)
|
||||
|
@ -55,16 +55,16 @@ typedef __uint32_t xfs_dir2_db_t;
|
||||
/*
|
||||
* Byte offset in a directory.
|
||||
*/
|
||||
typedef xfs_off_t xfs_dir2_off_t;
|
||||
typedef xfs_off_t xfs_dir2_off_t;
|
||||
|
||||
/*
|
||||
* For getdents, argument struct for put routines.
|
||||
*/
|
||||
typedef int (*xfs_dir2_put_t)(struct xfs_dir2_put_args *pa);
|
||||
typedef struct xfs_dir2_put_args {
|
||||
xfs_off_t cook; /* cookie of (next) entry */
|
||||
xfs_off_t cook; /* cookie of (next) entry */
|
||||
xfs_intino_t ino; /* inode number */
|
||||
struct xfs_dirent *dbp; /* buffer pointer */
|
||||
xfs_dirent_t *dbp; /* buffer pointer */
|
||||
char *name; /* directory entry name */
|
||||
int namelen; /* length of name */
|
||||
int done; /* output: set if value was stored */
|
||||
@ -75,18 +75,13 @@ typedef struct xfs_dir2_put_args {
|
||||
/*
|
||||
* Other interfaces used by the rest of the dir v2 code.
|
||||
*/
|
||||
extern int
|
||||
xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
|
||||
xfs_dir2_db_t *dbp);
|
||||
|
||||
extern int
|
||||
xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp, int *vp);
|
||||
|
||||
extern int
|
||||
xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *vp);
|
||||
|
||||
extern int
|
||||
xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
|
||||
struct xfs_dabuf *bp);
|
||||
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
|
||||
xfs_dir2_db_t *dbp);
|
||||
extern int xfs_dir2_isblock(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
int *vp);
|
||||
extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
int *vp);
|
||||
extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
|
||||
struct xfs_dabuf *bp);
|
||||
|
||||
#endif /* __XFS_DIR2_H__ */
|
||||
|
@ -81,7 +81,7 @@ xfs_dir2_block_addname(
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int needlog; /* need to log header */
|
||||
int needscan; /* need to rescan freespace */
|
||||
xfs_dir2_data_off_t *tagp; /* pointer to tag value */
|
||||
__be16 *tagp; /* pointer to tag value */
|
||||
xfs_trans_t *tp; /* transaction structure */
|
||||
|
||||
xfs_dir2_trace_args("block_addname", args);
|
||||
@ -100,8 +100,7 @@ xfs_dir2_block_addname(
|
||||
/*
|
||||
* Check the magic number, corrupted if wrong.
|
||||
*/
|
||||
if (unlikely(INT_GET(block->hdr.magic, ARCH_CONVERT)
|
||||
!= XFS_DIR2_BLOCK_MAGIC)) {
|
||||
if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) {
|
||||
XFS_CORRUPTION_ERROR("xfs_dir2_block_addname",
|
||||
XFS_ERRLEVEL_LOW, mp, block);
|
||||
xfs_da_brelse(tp, bp);
|
||||
@ -121,38 +120,38 @@ xfs_dir2_block_addname(
|
||||
/*
|
||||
* Tag just before the first leaf entry.
|
||||
*/
|
||||
tagp = (xfs_dir2_data_off_t *)blp - 1;
|
||||
tagp = (__be16 *)blp - 1;
|
||||
/*
|
||||
* Data object just before the first leaf entry.
|
||||
*/
|
||||
enddup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT));
|
||||
enddup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp));
|
||||
/*
|
||||
* If it's not free then can't do this add without cleaning up:
|
||||
* the space before the first leaf entry needs to be free so it
|
||||
* can be expanded to hold the pointer to the new entry.
|
||||
*/
|
||||
if (INT_GET(enddup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG)
|
||||
if (be16_to_cpu(enddup->freetag) != XFS_DIR2_DATA_FREE_TAG)
|
||||
dup = enddup = NULL;
|
||||
/*
|
||||
* Check out the biggest freespace and see if it's the same one.
|
||||
*/
|
||||
else {
|
||||
dup = (xfs_dir2_data_unused_t *)
|
||||
((char *)block + INT_GET(bf[0].offset, ARCH_CONVERT));
|
||||
((char *)block + be16_to_cpu(bf[0].offset));
|
||||
if (dup == enddup) {
|
||||
/*
|
||||
* It is the biggest freespace, is it too small
|
||||
* to hold the new leaf too?
|
||||
*/
|
||||
if (INT_GET(dup->length, ARCH_CONVERT) < len + (uint)sizeof(*blp)) {
|
||||
if (be16_to_cpu(dup->length) < len + (uint)sizeof(*blp)) {
|
||||
/*
|
||||
* Yes, we use the second-largest
|
||||
* entry instead if it works.
|
||||
*/
|
||||
if (INT_GET(bf[1].length, ARCH_CONVERT) >= len)
|
||||
if (be16_to_cpu(bf[1].length) >= len)
|
||||
dup = (xfs_dir2_data_unused_t *)
|
||||
((char *)block +
|
||||
INT_GET(bf[1].offset, ARCH_CONVERT));
|
||||
be16_to_cpu(bf[1].offset));
|
||||
else
|
||||
dup = NULL;
|
||||
}
|
||||
@ -161,7 +160,7 @@ xfs_dir2_block_addname(
|
||||
* Not the same free entry,
|
||||
* just check its length.
|
||||
*/
|
||||
if (INT_GET(dup->length, ARCH_CONVERT) < len) {
|
||||
if (be16_to_cpu(dup->length) < len) {
|
||||
dup = NULL;
|
||||
}
|
||||
}
|
||||
@ -172,9 +171,9 @@ xfs_dir2_block_addname(
|
||||
* If there are stale entries we'll use one for the leaf.
|
||||
* Is the biggest entry enough to avoid compaction?
|
||||
*/
|
||||
else if (INT_GET(bf[0].length, ARCH_CONVERT) >= len) {
|
||||
else if (be16_to_cpu(bf[0].length) >= len) {
|
||||
dup = (xfs_dir2_data_unused_t *)
|
||||
((char *)block + INT_GET(bf[0].offset, ARCH_CONVERT));
|
||||
((char *)block + be16_to_cpu(bf[0].offset));
|
||||
compact = 0;
|
||||
}
|
||||
/*
|
||||
@ -184,20 +183,20 @@ xfs_dir2_block_addname(
|
||||
/*
|
||||
* Tag just before the first leaf entry.
|
||||
*/
|
||||
tagp = (xfs_dir2_data_off_t *)blp - 1;
|
||||
tagp = (__be16 *)blp - 1;
|
||||
/*
|
||||
* Data object just before the first leaf entry.
|
||||
*/
|
||||
dup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT));
|
||||
dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp));
|
||||
/*
|
||||
* If it's not free then the data will go where the
|
||||
* leaf data starts now, if it works at all.
|
||||
*/
|
||||
if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
if (INT_GET(dup->length, ARCH_CONVERT) + (INT_GET(btp->stale, ARCH_CONVERT) - 1) *
|
||||
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
if (be16_to_cpu(dup->length) + (be32_to_cpu(btp->stale) - 1) *
|
||||
(uint)sizeof(*blp) < len)
|
||||
dup = NULL;
|
||||
} else if ((INT_GET(btp->stale, ARCH_CONVERT) - 1) * (uint)sizeof(*blp) < len)
|
||||
} else if ((be32_to_cpu(btp->stale) - 1) * (uint)sizeof(*blp) < len)
|
||||
dup = NULL;
|
||||
else
|
||||
dup = (xfs_dir2_data_unused_t *)blp;
|
||||
@ -243,11 +242,11 @@ xfs_dir2_block_addname(
|
||||
int fromidx; /* source leaf index */
|
||||
int toidx; /* target leaf index */
|
||||
|
||||
for (fromidx = toidx = INT_GET(btp->count, ARCH_CONVERT) - 1,
|
||||
for (fromidx = toidx = be32_to_cpu(btp->count) - 1,
|
||||
highstale = lfloghigh = -1;
|
||||
fromidx >= 0;
|
||||
fromidx--) {
|
||||
if (INT_GET(blp[fromidx].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) {
|
||||
if (be32_to_cpu(blp[fromidx].address) == XFS_DIR2_NULL_DATAPTR) {
|
||||
if (highstale == -1)
|
||||
highstale = toidx;
|
||||
else {
|
||||
@ -260,15 +259,15 @@ xfs_dir2_block_addname(
|
||||
blp[toidx] = blp[fromidx];
|
||||
toidx--;
|
||||
}
|
||||
lfloglow = toidx + 1 - (INT_GET(btp->stale, ARCH_CONVERT) - 1);
|
||||
lfloghigh -= INT_GET(btp->stale, ARCH_CONVERT) - 1;
|
||||
INT_MOD(btp->count, ARCH_CONVERT, -(INT_GET(btp->stale, ARCH_CONVERT) - 1));
|
||||
lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1);
|
||||
lfloghigh -= be32_to_cpu(btp->stale) - 1;
|
||||
be32_add(&btp->count, -(be32_to_cpu(btp->stale) - 1));
|
||||
xfs_dir2_data_make_free(tp, bp,
|
||||
(xfs_dir2_data_aoff_t)((char *)blp - (char *)block),
|
||||
(xfs_dir2_data_aoff_t)((INT_GET(btp->stale, ARCH_CONVERT) - 1) * sizeof(*blp)),
|
||||
(xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
|
||||
&needlog, &needscan);
|
||||
blp += INT_GET(btp->stale, ARCH_CONVERT) - 1;
|
||||
INT_SET(btp->stale, ARCH_CONVERT, 1);
|
||||
blp += be32_to_cpu(btp->stale) - 1;
|
||||
btp->stale = cpu_to_be32(1);
|
||||
/*
|
||||
* If we now need to rebuild the bestfree map, do so.
|
||||
* This needs to happen before the next call to use_free.
|
||||
@ -283,23 +282,23 @@ xfs_dir2_block_addname(
|
||||
* Set leaf logging boundaries to impossible state.
|
||||
* For the no-stale case they're set explicitly.
|
||||
*/
|
||||
else if (INT_GET(btp->stale, ARCH_CONVERT)) {
|
||||
lfloglow = INT_GET(btp->count, ARCH_CONVERT);
|
||||
else if (btp->stale) {
|
||||
lfloglow = be32_to_cpu(btp->count);
|
||||
lfloghigh = -1;
|
||||
}
|
||||
/*
|
||||
* Find the slot that's first lower than our hash value, -1 if none.
|
||||
*/
|
||||
for (low = 0, high = INT_GET(btp->count, ARCH_CONVERT) - 1; low <= high; ) {
|
||||
for (low = 0, high = be32_to_cpu(btp->count) - 1; low <= high; ) {
|
||||
mid = (low + high) >> 1;
|
||||
if ((hash = INT_GET(blp[mid].hashval, ARCH_CONVERT)) == args->hashval)
|
||||
if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval)
|
||||
break;
|
||||
if (hash < args->hashval)
|
||||
low = mid + 1;
|
||||
else
|
||||
high = mid - 1;
|
||||
}
|
||||
while (mid >= 0 && INT_GET(blp[mid].hashval, ARCH_CONVERT) >= args->hashval) {
|
||||
while (mid >= 0 && be32_to_cpu(blp[mid].hashval) >= args->hashval) {
|
||||
mid--;
|
||||
}
|
||||
/*
|
||||
@ -311,14 +310,14 @@ xfs_dir2_block_addname(
|
||||
*/
|
||||
xfs_dir2_data_use_free(tp, bp, enddup,
|
||||
(xfs_dir2_data_aoff_t)
|
||||
((char *)enddup - (char *)block + INT_GET(enddup->length, ARCH_CONVERT) -
|
||||
((char *)enddup - (char *)block + be16_to_cpu(enddup->length) -
|
||||
sizeof(*blp)),
|
||||
(xfs_dir2_data_aoff_t)sizeof(*blp),
|
||||
&needlog, &needscan);
|
||||
/*
|
||||
* Update the tail (entry count).
|
||||
*/
|
||||
INT_MOD(btp->count, ARCH_CONVERT, +1);
|
||||
be32_add(&btp->count, 1);
|
||||
/*
|
||||
* If we now need to rebuild the bestfree map, do so.
|
||||
* This needs to happen before the next call to use_free.
|
||||
@ -346,12 +345,12 @@ xfs_dir2_block_addname(
|
||||
else {
|
||||
for (lowstale = mid;
|
||||
lowstale >= 0 &&
|
||||
INT_GET(blp[lowstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR;
|
||||
be32_to_cpu(blp[lowstale].address) != XFS_DIR2_NULL_DATAPTR;
|
||||
lowstale--)
|
||||
continue;
|
||||
for (highstale = mid + 1;
|
||||
highstale < INT_GET(btp->count, ARCH_CONVERT) &&
|
||||
INT_GET(blp[highstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR &&
|
||||
highstale < be32_to_cpu(btp->count) &&
|
||||
be32_to_cpu(blp[highstale].address) != XFS_DIR2_NULL_DATAPTR &&
|
||||
(lowstale < 0 || mid - lowstale > highstale - mid);
|
||||
highstale++)
|
||||
continue;
|
||||
@ -359,7 +358,7 @@ xfs_dir2_block_addname(
|
||||
* Move entries toward the low-numbered stale entry.
|
||||
*/
|
||||
if (lowstale >= 0 &&
|
||||
(highstale == INT_GET(btp->count, ARCH_CONVERT) ||
|
||||
(highstale == be32_to_cpu(btp->count) ||
|
||||
mid - lowstale <= highstale - mid)) {
|
||||
if (mid - lowstale)
|
||||
memmove(&blp[lowstale], &blp[lowstale + 1],
|
||||
@ -371,7 +370,7 @@ xfs_dir2_block_addname(
|
||||
* Move entries toward the high-numbered stale entry.
|
||||
*/
|
||||
else {
|
||||
ASSERT(highstale < INT_GET(btp->count, ARCH_CONVERT));
|
||||
ASSERT(highstale < be32_to_cpu(btp->count));
|
||||
mid++;
|
||||
if (highstale - mid)
|
||||
memmove(&blp[mid + 1], &blp[mid],
|
||||
@ -379,7 +378,7 @@ xfs_dir2_block_addname(
|
||||
lfloglow = MIN(mid, lfloglow);
|
||||
lfloghigh = MAX(highstale, lfloghigh);
|
||||
}
|
||||
INT_MOD(btp->stale, ARCH_CONVERT, -1);
|
||||
be32_add(&btp->stale, -1);
|
||||
}
|
||||
/*
|
||||
* Point to the new data entry.
|
||||
@ -388,8 +387,9 @@ xfs_dir2_block_addname(
|
||||
/*
|
||||
* Fill in the leaf entry.
|
||||
*/
|
||||
INT_SET(blp[mid].hashval, ARCH_CONVERT, args->hashval);
|
||||
INT_SET(blp[mid].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block));
|
||||
blp[mid].hashval = cpu_to_be32(args->hashval);
|
||||
blp[mid].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp,
|
||||
(char *)dep - (char *)block));
|
||||
xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh);
|
||||
/*
|
||||
* Mark space for the data entry used.
|
||||
@ -404,7 +404,7 @@ xfs_dir2_block_addname(
|
||||
dep->namelen = args->namelen;
|
||||
memcpy(dep->name, args->name, args->namelen);
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block));
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)block);
|
||||
/*
|
||||
* Clean up the bestfree array and log the header, tail, and entry.
|
||||
*/
|
||||
@ -485,8 +485,8 @@ xfs_dir2_block_getdents(
|
||||
/*
|
||||
* Unused, skip it.
|
||||
*/
|
||||
if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
ptr += INT_GET(dup->length, ARCH_CONVERT);
|
||||
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
ptr += be16_to_cpu(dup->length);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -622,7 +622,7 @@ xfs_dir2_block_lookup(
|
||||
* Get the offset from the leaf entry, to point to the data.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT)));
|
||||
((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
|
||||
/*
|
||||
* Fill in inode number, release the block.
|
||||
*/
|
||||
@ -674,10 +674,10 @@ xfs_dir2_block_lookup_int(
|
||||
* Loop doing a binary search for our hash value.
|
||||
* Find our entry, ENOENT if it's not there.
|
||||
*/
|
||||
for (low = 0, high = INT_GET(btp->count, ARCH_CONVERT) - 1; ; ) {
|
||||
for (low = 0, high = be32_to_cpu(btp->count) - 1; ; ) {
|
||||
ASSERT(low <= high);
|
||||
mid = (low + high) >> 1;
|
||||
if ((hash = INT_GET(blp[mid].hashval, ARCH_CONVERT)) == args->hashval)
|
||||
if ((hash = be32_to_cpu(blp[mid].hashval)) == args->hashval)
|
||||
break;
|
||||
if (hash < args->hashval)
|
||||
low = mid + 1;
|
||||
@ -692,7 +692,7 @@ xfs_dir2_block_lookup_int(
|
||||
/*
|
||||
* Back up to the first one with the right hash value.
|
||||
*/
|
||||
while (mid > 0 && INT_GET(blp[mid - 1].hashval, ARCH_CONVERT) == args->hashval) {
|
||||
while (mid > 0 && be32_to_cpu(blp[mid - 1].hashval) == args->hashval) {
|
||||
mid--;
|
||||
}
|
||||
/*
|
||||
@ -700,7 +700,7 @@ xfs_dir2_block_lookup_int(
|
||||
* right hash value looking for our name.
|
||||
*/
|
||||
do {
|
||||
if ((addr = INT_GET(blp[mid].address, ARCH_CONVERT)) == XFS_DIR2_NULL_DATAPTR)
|
||||
if ((addr = be32_to_cpu(blp[mid].address)) == XFS_DIR2_NULL_DATAPTR)
|
||||
continue;
|
||||
/*
|
||||
* Get pointer to the entry from the leaf.
|
||||
@ -717,7 +717,7 @@ xfs_dir2_block_lookup_int(
|
||||
*entno = mid;
|
||||
return 0;
|
||||
}
|
||||
} while (++mid < INT_GET(btp->count, ARCH_CONVERT) && INT_GET(blp[mid].hashval, ARCH_CONVERT) == hash);
|
||||
} while (++mid < be32_to_cpu(btp->count) && be32_to_cpu(blp[mid].hashval) == hash);
|
||||
/*
|
||||
* No match, release the buffer and return ENOENT.
|
||||
*/
|
||||
@ -767,7 +767,7 @@ xfs_dir2_block_removename(
|
||||
* Point to the data entry using the leaf entry.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT)));
|
||||
((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
|
||||
/*
|
||||
* Mark the data entry's space free.
|
||||
*/
|
||||
@ -778,12 +778,12 @@ xfs_dir2_block_removename(
|
||||
/*
|
||||
* Fix up the block tail.
|
||||
*/
|
||||
INT_MOD(btp->stale, ARCH_CONVERT, +1);
|
||||
be32_add(&btp->stale, 1);
|
||||
xfs_dir2_block_log_tail(tp, bp);
|
||||
/*
|
||||
* Remove the leaf entry by marking it stale.
|
||||
*/
|
||||
INT_SET(blp[ent].address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR);
|
||||
blp[ent].address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
|
||||
xfs_dir2_block_log_leaf(tp, bp, ent, ent);
|
||||
/*
|
||||
* Fix up bestfree, log the header if necessary.
|
||||
@ -843,7 +843,7 @@ xfs_dir2_block_replace(
|
||||
* Point to the data entry we need to change.
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(blp[ent].address, ARCH_CONVERT)));
|
||||
((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address)));
|
||||
ASSERT(INT_GET(dep->inumber, ARCH_CONVERT) != args->inumber);
|
||||
/*
|
||||
* Change the inode number to the new value.
|
||||
@ -868,8 +868,8 @@ xfs_dir2_block_sort(
|
||||
|
||||
la = a;
|
||||
lb = b;
|
||||
return INT_GET(la->hashval, ARCH_CONVERT) < INT_GET(lb->hashval, ARCH_CONVERT) ? -1 :
|
||||
(INT_GET(la->hashval, ARCH_CONVERT) > INT_GET(lb->hashval, ARCH_CONVERT) ? 1 : 0);
|
||||
return be32_to_cpu(la->hashval) < be32_to_cpu(lb->hashval) ? -1 :
|
||||
(be32_to_cpu(la->hashval) > be32_to_cpu(lb->hashval) ? 1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -881,7 +881,7 @@ xfs_dir2_leaf_to_block(
|
||||
xfs_dabuf_t *lbp, /* leaf buffer */
|
||||
xfs_dabuf_t *dbp) /* data buffer */
|
||||
{
|
||||
xfs_dir2_data_off_t *bestsp; /* leaf bests table */
|
||||
__be16 *bestsp; /* leaf bests table */
|
||||
xfs_dir2_block_t *block; /* block structure */
|
||||
xfs_dir2_block_tail_t *btp; /* block tail */
|
||||
xfs_inode_t *dp; /* incore directory inode */
|
||||
@ -896,7 +896,7 @@ xfs_dir2_leaf_to_block(
|
||||
int needscan; /* need to scan for bestfree */
|
||||
xfs_dir2_sf_hdr_t sfh; /* shortform header */
|
||||
int size; /* bytes used */
|
||||
xfs_dir2_data_off_t *tagp; /* end of entry (tag) */
|
||||
__be16 *tagp; /* end of entry (tag) */
|
||||
int to; /* block/leaf to index */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
|
||||
@ -905,7 +905,7 @@ xfs_dir2_leaf_to_block(
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
leaf = lbp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC);
|
||||
ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
|
||||
/*
|
||||
* If there are data blocks other than the first one, take this
|
||||
@ -915,11 +915,11 @@ xfs_dir2_leaf_to_block(
|
||||
*/
|
||||
while (dp->i_d.di_size > mp->m_dirblksize) {
|
||||
bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
|
||||
if (INT_GET(bestsp[INT_GET(ltp->bestcount, ARCH_CONVERT) - 1], ARCH_CONVERT) ==
|
||||
if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) ==
|
||||
mp->m_dirblksize - (uint)sizeof(block->hdr)) {
|
||||
if ((error =
|
||||
xfs_dir2_leaf_trim_data(args, lbp,
|
||||
(xfs_dir2_db_t)(INT_GET(ltp->bestcount, ARCH_CONVERT) - 1))))
|
||||
(xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1))))
|
||||
goto out;
|
||||
} else {
|
||||
error = 0;
|
||||
@ -935,28 +935,29 @@ xfs_dir2_leaf_to_block(
|
||||
goto out;
|
||||
}
|
||||
block = dbp->data;
|
||||
ASSERT(INT_GET(block->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC);
|
||||
ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC);
|
||||
/*
|
||||
* Size of the "leaf" area in the block.
|
||||
*/
|
||||
size = (uint)sizeof(block->tail) +
|
||||
(uint)sizeof(*lep) * (INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT));
|
||||
(uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale));
|
||||
/*
|
||||
* Look at the last data entry.
|
||||
*/
|
||||
tagp = (xfs_dir2_data_off_t *)((char *)block + mp->m_dirblksize) - 1;
|
||||
dup = (xfs_dir2_data_unused_t *)((char *)block + INT_GET(*tagp, ARCH_CONVERT));
|
||||
tagp = (__be16 *)((char *)block + mp->m_dirblksize) - 1;
|
||||
dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp));
|
||||
/*
|
||||
* If it's not free or is too short we can't do it.
|
||||
*/
|
||||
if (INT_GET(dup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG || INT_GET(dup->length, ARCH_CONVERT) < size) {
|
||||
if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG ||
|
||||
be16_to_cpu(dup->length) < size) {
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Start converting it to block form.
|
||||
*/
|
||||
INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_BLOCK_MAGIC);
|
||||
block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
|
||||
needlog = 1;
|
||||
needscan = 0;
|
||||
/*
|
||||
@ -968,20 +969,20 @@ xfs_dir2_leaf_to_block(
|
||||
* Initialize the block tail.
|
||||
*/
|
||||
btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
|
||||
INT_SET(btp->count, ARCH_CONVERT, INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT));
|
||||
btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale));
|
||||
btp->stale = 0;
|
||||
xfs_dir2_block_log_tail(tp, dbp);
|
||||
/*
|
||||
* Initialize the block leaf area. We compact out stale entries.
|
||||
*/
|
||||
lep = XFS_DIR2_BLOCK_LEAF_P(btp);
|
||||
for (from = to = 0; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) {
|
||||
if (INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
|
||||
for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) {
|
||||
if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR)
|
||||
continue;
|
||||
lep[to++] = leaf->ents[from];
|
||||
}
|
||||
ASSERT(to == INT_GET(btp->count, ARCH_CONVERT));
|
||||
xfs_dir2_block_log_leaf(tp, dbp, 0, INT_GET(btp->count, ARCH_CONVERT) - 1);
|
||||
ASSERT(to == be32_to_cpu(btp->count));
|
||||
xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1);
|
||||
/*
|
||||
* Scan the bestfree if we need it and log the data block header.
|
||||
*/
|
||||
@ -1043,7 +1044,7 @@ xfs_dir2_sf_to_block(
|
||||
int offset; /* target block offset */
|
||||
xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */
|
||||
xfs_dir2_sf_t *sfp; /* shortform structure */
|
||||
xfs_dir2_data_off_t *tagp; /* end of data entry */
|
||||
__be16 *tagp; /* end of data entry */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
|
||||
xfs_dir2_trace_args("sf_to_block", args);
|
||||
@ -1095,12 +1096,12 @@ xfs_dir2_sf_to_block(
|
||||
return error;
|
||||
}
|
||||
block = bp->data;
|
||||
INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_BLOCK_MAGIC);
|
||||
block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
|
||||
/*
|
||||
* Compute size of block "tail" area.
|
||||
*/
|
||||
i = (uint)sizeof(*btp) +
|
||||
(INT_GET(sfp->hdr.count, ARCH_CONVERT) + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t);
|
||||
(sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t);
|
||||
/*
|
||||
* The whole thing is initialized to free by the init routine.
|
||||
* Say we're using the leaf and tail area.
|
||||
@ -1114,7 +1115,7 @@ xfs_dir2_sf_to_block(
|
||||
* Fill in the tail.
|
||||
*/
|
||||
btp = XFS_DIR2_BLOCK_TAIL_P(mp, block);
|
||||
INT_SET(btp->count, ARCH_CONVERT, INT_GET(sfp->hdr.count, ARCH_CONVERT) + 2); /* ., .. */
|
||||
btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */
|
||||
btp->stale = 0;
|
||||
blp = XFS_DIR2_BLOCK_LEAF_P(btp);
|
||||
endoffset = (uint)((char *)blp - (char *)block);
|
||||
@ -1123,7 +1124,7 @@ xfs_dir2_sf_to_block(
|
||||
*/
|
||||
xfs_dir2_data_use_free(tp, bp, dup,
|
||||
(xfs_dir2_data_aoff_t)((char *)dup - (char *)block),
|
||||
INT_GET(dup->length, ARCH_CONVERT), &needlog, &needscan);
|
||||
be16_to_cpu(dup->length), &needlog, &needscan);
|
||||
/*
|
||||
* Create entry for .
|
||||
*/
|
||||
@ -1133,10 +1134,11 @@ xfs_dir2_sf_to_block(
|
||||
dep->namelen = 1;
|
||||
dep->name[0] = '.';
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block));
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)block);
|
||||
xfs_dir2_data_log_entry(tp, bp, dep);
|
||||
INT_SET(blp[0].hashval, ARCH_CONVERT, xfs_dir_hash_dot);
|
||||
INT_SET(blp[0].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block));
|
||||
blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
|
||||
blp[0].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp,
|
||||
(char *)dep - (char *)block));
|
||||
/*
|
||||
* Create entry for ..
|
||||
*/
|
||||
@ -1146,15 +1148,16 @@ xfs_dir2_sf_to_block(
|
||||
dep->namelen = 2;
|
||||
dep->name[0] = dep->name[1] = '.';
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block));
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)block);
|
||||
xfs_dir2_data_log_entry(tp, bp, dep);
|
||||
INT_SET(blp[1].hashval, ARCH_CONVERT, xfs_dir_hash_dotdot);
|
||||
INT_SET(blp[1].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp, (char *)dep - (char *)block));
|
||||
blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
|
||||
blp[1].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp,
|
||||
(char *)dep - (char *)block));
|
||||
offset = XFS_DIR2_DATA_FIRST_OFFSET;
|
||||
/*
|
||||
* Loop over existing entries, stuff them in.
|
||||
*/
|
||||
if ((i = 0) == INT_GET(sfp->hdr.count, ARCH_CONVERT))
|
||||
if ((i = 0) == sfp->hdr.count)
|
||||
sfep = NULL;
|
||||
else
|
||||
sfep = XFS_DIR2_SF_FIRSTENTRY(sfp);
|
||||
@ -1176,15 +1179,14 @@ xfs_dir2_sf_to_block(
|
||||
if (offset < newoffset) {
|
||||
dup = (xfs_dir2_data_unused_t *)
|
||||
((char *)block + offset);
|
||||
INT_SET(dup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
|
||||
INT_SET(dup->length, ARCH_CONVERT, newoffset - offset);
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)
|
||||
dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
|
||||
dup->length = cpu_to_be16(newoffset - offset);
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(dup) = cpu_to_be16(
|
||||
((char *)dup - (char *)block));
|
||||
xfs_dir2_data_log_unused(tp, bp, dup);
|
||||
(void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block,
|
||||
dup, &dummy);
|
||||
offset += INT_GET(dup->length, ARCH_CONVERT);
|
||||
offset += be16_to_cpu(dup->length);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@ -1196,13 +1198,14 @@ xfs_dir2_sf_to_block(
|
||||
dep->namelen = sfep->namelen;
|
||||
memcpy(dep->name, sfep->name, dep->namelen);
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)block));
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)block);
|
||||
xfs_dir2_data_log_entry(tp, bp, dep);
|
||||
INT_SET(blp[2 + i].hashval, ARCH_CONVERT, xfs_da_hashname((char *)sfep->name, sfep->namelen));
|
||||
INT_SET(blp[2 + i].address, ARCH_CONVERT, XFS_DIR2_BYTE_TO_DATAPTR(mp,
|
||||
blp[2 + i].hashval = cpu_to_be32(xfs_da_hashname(
|
||||
(char *)sfep->name, sfep->namelen));
|
||||
blp[2 + i].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp,
|
||||
(char *)dep - (char *)block));
|
||||
offset = (int)((char *)(tagp + 1) - (char *)block);
|
||||
if (++i == INT_GET(sfp->hdr.count, ARCH_CONVERT))
|
||||
if (++i == sfp->hdr.count)
|
||||
sfep = NULL;
|
||||
else
|
||||
sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep);
|
||||
@ -1212,13 +1215,13 @@ xfs_dir2_sf_to_block(
|
||||
/*
|
||||
* Sort the leaf entries by hash value.
|
||||
*/
|
||||
xfs_sort(blp, INT_GET(btp->count, ARCH_CONVERT), sizeof(*blp), xfs_dir2_block_sort);
|
||||
xfs_sort(blp, be32_to_cpu(btp->count), sizeof(*blp), xfs_dir2_block_sort);
|
||||
/*
|
||||
* Log the leaf entry area and tail.
|
||||
* Already logged the header in data_init, ignore needlog.
|
||||
*/
|
||||
ASSERT(needscan == 0);
|
||||
xfs_dir2_block_log_leaf(tp, bp, 0, INT_GET(btp->count, ARCH_CONVERT) - 1);
|
||||
xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1);
|
||||
xfs_dir2_block_log_tail(tp, bp);
|
||||
xfs_dir2_data_check(dp, bp);
|
||||
xfs_da_buf_done(bp);
|
||||
|
@ -43,8 +43,8 @@ struct xfs_trans;
|
||||
#define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */
|
||||
|
||||
typedef struct xfs_dir2_block_tail {
|
||||
__uint32_t count; /* count of leaf entries */
|
||||
__uint32_t stale; /* count of stale lf entries */
|
||||
__be32 count; /* count of leaf entries */
|
||||
__be32 stale; /* count of stale lf entries */
|
||||
} xfs_dir2_block_tail_t;
|
||||
|
||||
/*
|
||||
@ -75,8 +75,7 @@ xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block)
|
||||
static inline struct xfs_dir2_leaf_entry *
|
||||
xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp)
|
||||
{
|
||||
return (((struct xfs_dir2_leaf_entry *)
|
||||
(btp)) - INT_GET((btp)->count, ARCH_CONVERT));
|
||||
return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -70,11 +70,11 @@ xfs_dir2_data_check(
|
||||
|
||||
mp = dp->i_mount;
|
||||
d = bp->data;
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
|
||||
INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
|
||||
be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
bf = d->hdr.bestfree;
|
||||
p = (char *)d->u;
|
||||
if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
|
||||
lep = XFS_DIR2_BLOCK_LEAF_P(btp);
|
||||
endp = (char *)lep;
|
||||
@ -96,8 +96,8 @@ xfs_dir2_data_check(
|
||||
ASSERT(!bf[2].offset);
|
||||
freeseen |= 1 << 2;
|
||||
}
|
||||
ASSERT(INT_GET(bf[0].length, ARCH_CONVERT) >= INT_GET(bf[1].length, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(bf[1].length, ARCH_CONVERT) >= INT_GET(bf[2].length, ARCH_CONVERT));
|
||||
ASSERT(be16_to_cpu(bf[0].length) >= be16_to_cpu(bf[1].length));
|
||||
ASSERT(be16_to_cpu(bf[1].length) >= be16_to_cpu(bf[2].length));
|
||||
/*
|
||||
* Loop over the data/unused entries.
|
||||
*/
|
||||
@ -108,18 +108,20 @@ xfs_dir2_data_check(
|
||||
* If we find it, account for that, else make sure it
|
||||
* doesn't need to be there.
|
||||
*/
|
||||
if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
ASSERT(lastfree == 0);
|
||||
ASSERT(INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT) ==
|
||||
ASSERT(be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup)) ==
|
||||
(char *)dup - (char *)d);
|
||||
dfp = xfs_dir2_data_freefind(d, dup);
|
||||
if (dfp) {
|
||||
i = (int)(dfp - bf);
|
||||
ASSERT((freeseen & (1 << i)) == 0);
|
||||
freeseen |= 1 << i;
|
||||
} else
|
||||
ASSERT(INT_GET(dup->length, ARCH_CONVERT) <= INT_GET(bf[2].length, ARCH_CONVERT));
|
||||
p += INT_GET(dup->length, ARCH_CONVERT);
|
||||
} else {
|
||||
ASSERT(be16_to_cpu(dup->length) <=
|
||||
be16_to_cpu(bf[2].length));
|
||||
}
|
||||
p += be16_to_cpu(dup->length);
|
||||
lastfree = 1;
|
||||
continue;
|
||||
}
|
||||
@ -132,21 +134,21 @@ xfs_dir2_data_check(
|
||||
dep = (xfs_dir2_data_entry_t *)p;
|
||||
ASSERT(dep->namelen != 0);
|
||||
ASSERT(xfs_dir_ino_validate(mp, INT_GET(dep->inumber, ARCH_CONVERT)) == 0);
|
||||
ASSERT(INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT) ==
|
||||
ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) ==
|
||||
(char *)dep - (char *)d);
|
||||
count++;
|
||||
lastfree = 0;
|
||||
if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk,
|
||||
(xfs_dir2_data_aoff_t)
|
||||
((char *)dep - (char *)d));
|
||||
hash = xfs_da_hashname((char *)dep->name, dep->namelen);
|
||||
for (i = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) {
|
||||
if (INT_GET(lep[i].address, ARCH_CONVERT) == addr &&
|
||||
INT_GET(lep[i].hashval, ARCH_CONVERT) == hash)
|
||||
for (i = 0; i < be32_to_cpu(btp->count); i++) {
|
||||
if (be32_to_cpu(lep[i].address) == addr &&
|
||||
be32_to_cpu(lep[i].hashval) == hash)
|
||||
break;
|
||||
}
|
||||
ASSERT(i < INT_GET(btp->count, ARCH_CONVERT));
|
||||
ASSERT(i < be32_to_cpu(btp->count));
|
||||
}
|
||||
p += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
|
||||
}
|
||||
@ -154,15 +156,15 @@ xfs_dir2_data_check(
|
||||
* Need to have seen all the entries and all the bestfree slots.
|
||||
*/
|
||||
ASSERT(freeseen == 7);
|
||||
if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
for (i = stale = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) {
|
||||
if (INT_GET(lep[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
|
||||
if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
for (i = stale = 0; i < be32_to_cpu(btp->count); i++) {
|
||||
if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR)
|
||||
stale++;
|
||||
if (i > 0)
|
||||
ASSERT(INT_GET(lep[i].hashval, ARCH_CONVERT) >= INT_GET(lep[i - 1].hashval, ARCH_CONVERT));
|
||||
ASSERT(be32_to_cpu(lep[i].hashval) >= be32_to_cpu(lep[i - 1].hashval));
|
||||
}
|
||||
ASSERT(count == INT_GET(btp->count, ARCH_CONVERT) - INT_GET(btp->stale, ARCH_CONVERT));
|
||||
ASSERT(stale == INT_GET(btp->stale, ARCH_CONVERT));
|
||||
ASSERT(count == be32_to_cpu(btp->count) - be32_to_cpu(btp->stale));
|
||||
ASSERT(stale == be32_to_cpu(btp->stale));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -190,8 +192,8 @@ xfs_dir2_data_freefind(
|
||||
* Check order, non-overlapping entries, and if we find the
|
||||
* one we're looking for it has to be exact.
|
||||
*/
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
|
||||
INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
|
||||
be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0;
|
||||
dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT];
|
||||
dfp++) {
|
||||
@ -201,23 +203,24 @@ xfs_dir2_data_freefind(
|
||||
continue;
|
||||
}
|
||||
ASSERT(seenzero == 0);
|
||||
if (INT_GET(dfp->offset, ARCH_CONVERT) == off) {
|
||||
if (be16_to_cpu(dfp->offset) == off) {
|
||||
matched = 1;
|
||||
ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(dup->length, ARCH_CONVERT));
|
||||
} else if (off < INT_GET(dfp->offset, ARCH_CONVERT))
|
||||
ASSERT(off + INT_GET(dup->length, ARCH_CONVERT) <= INT_GET(dfp->offset, ARCH_CONVERT));
|
||||
ASSERT(dfp->length == dup->length);
|
||||
} else if (off < be16_to_cpu(dfp->offset))
|
||||
ASSERT(off + be16_to_cpu(dup->length) <= be16_to_cpu(dfp->offset));
|
||||
else
|
||||
ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) + INT_GET(dfp->length, ARCH_CONVERT) <= off);
|
||||
ASSERT(matched || INT_GET(dfp->length, ARCH_CONVERT) >= INT_GET(dup->length, ARCH_CONVERT));
|
||||
ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off);
|
||||
ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length));
|
||||
if (dfp > &d->hdr.bestfree[0])
|
||||
ASSERT(INT_GET(dfp[-1].length, ARCH_CONVERT) >= INT_GET(dfp[0].length, ARCH_CONVERT));
|
||||
ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length));
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* If this is smaller than the smallest bestfree entry,
|
||||
* it can't be there since they're sorted.
|
||||
*/
|
||||
if (INT_GET(dup->length, ARCH_CONVERT) < INT_GET(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length, ARCH_CONVERT))
|
||||
if (be16_to_cpu(dup->length) <
|
||||
be16_to_cpu(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length))
|
||||
return NULL;
|
||||
/*
|
||||
* Look at the three bestfree entries for our guy.
|
||||
@ -227,7 +230,7 @@ xfs_dir2_data_freefind(
|
||||
dfp++) {
|
||||
if (!dfp->offset)
|
||||
return NULL;
|
||||
if (INT_GET(dfp->offset, ARCH_CONVERT) == off)
|
||||
if (be16_to_cpu(dfp->offset) == off)
|
||||
return dfp;
|
||||
}
|
||||
/*
|
||||
@ -249,29 +252,29 @@ xfs_dir2_data_freeinsert(
|
||||
xfs_dir2_data_free_t new; /* new bestfree entry */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
|
||||
INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
|
||||
be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
#endif
|
||||
dfp = d->hdr.bestfree;
|
||||
INT_COPY(new.length, dup->length, ARCH_CONVERT);
|
||||
INT_SET(new.offset, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dup - (char *)d));
|
||||
new.length = dup->length;
|
||||
new.offset = cpu_to_be16((char *)dup - (char *)d);
|
||||
/*
|
||||
* Insert at position 0, 1, or 2; or not at all.
|
||||
*/
|
||||
if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[0].length, ARCH_CONVERT)) {
|
||||
if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) {
|
||||
dfp[2] = dfp[1];
|
||||
dfp[1] = dfp[0];
|
||||
dfp[0] = new;
|
||||
*loghead = 1;
|
||||
return &dfp[0];
|
||||
}
|
||||
if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[1].length, ARCH_CONVERT)) {
|
||||
if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) {
|
||||
dfp[2] = dfp[1];
|
||||
dfp[1] = new;
|
||||
*loghead = 1;
|
||||
return &dfp[1];
|
||||
}
|
||||
if (INT_GET(new.length, ARCH_CONVERT) > INT_GET(dfp[2].length, ARCH_CONVERT)) {
|
||||
if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) {
|
||||
dfp[2] = new;
|
||||
*loghead = 1;
|
||||
return &dfp[2];
|
||||
@ -289,8 +292,8 @@ xfs_dir2_data_freeremove(
|
||||
int *loghead) /* out: log data header */
|
||||
{
|
||||
#ifdef __KERNEL__
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
|
||||
INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
|
||||
be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
#endif
|
||||
/*
|
||||
* It's the first entry, slide the next 2 up.
|
||||
@ -334,8 +337,8 @@ xfs_dir2_data_freescan(
|
||||
char *p; /* current entry pointer */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
|
||||
INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
|
||||
be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
#endif
|
||||
/*
|
||||
* Start by clearing the table.
|
||||
@ -348,7 +351,7 @@ xfs_dir2_data_freescan(
|
||||
p = (char *)d->u;
|
||||
if (aendp)
|
||||
endp = aendp;
|
||||
else if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
else if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) {
|
||||
btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
|
||||
endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
|
||||
} else
|
||||
@ -361,11 +364,11 @@ xfs_dir2_data_freescan(
|
||||
/*
|
||||
* If it's a free entry, insert it.
|
||||
*/
|
||||
if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
ASSERT((char *)dup - (char *)d ==
|
||||
INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT));
|
||||
be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup)));
|
||||
xfs_dir2_data_freeinsert(d, dup, loghead);
|
||||
p += INT_GET(dup->length, ARCH_CONVERT);
|
||||
p += be16_to_cpu(dup->length);
|
||||
}
|
||||
/*
|
||||
* For active entries, check their tags and skip them.
|
||||
@ -373,7 +376,7 @@ xfs_dir2_data_freescan(
|
||||
else {
|
||||
dep = (xfs_dir2_data_entry_t *)p;
|
||||
ASSERT((char *)dep - (char *)d ==
|
||||
INT_GET(*XFS_DIR2_DATA_ENTRY_TAG_P(dep), ARCH_CONVERT));
|
||||
be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)));
|
||||
p += XFS_DIR2_DATA_ENTSIZE(dep->namelen);
|
||||
}
|
||||
}
|
||||
@ -415,8 +418,8 @@ xfs_dir2_data_init(
|
||||
* Initialize the header.
|
||||
*/
|
||||
d = bp->data;
|
||||
INT_SET(d->hdr.magic, ARCH_CONVERT, XFS_DIR2_DATA_MAGIC);
|
||||
INT_SET(d->hdr.bestfree[0].offset, ARCH_CONVERT, (xfs_dir2_data_off_t)sizeof(d->hdr));
|
||||
d->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
|
||||
d->hdr.bestfree[0].offset = cpu_to_be16(sizeof(d->hdr));
|
||||
for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
|
||||
d->hdr.bestfree[i].length = 0;
|
||||
d->hdr.bestfree[i].offset = 0;
|
||||
@ -425,13 +428,12 @@ xfs_dir2_data_init(
|
||||
* Set up an unused entry for the block's body.
|
||||
*/
|
||||
dup = &d->u[0].unused;
|
||||
INT_SET(dup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
|
||||
dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
|
||||
|
||||
t=mp->m_dirblksize - (uint)sizeof(d->hdr);
|
||||
INT_SET(d->hdr.bestfree[0].length, ARCH_CONVERT, t);
|
||||
INT_SET(dup->length, ARCH_CONVERT, t);
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)((char *)dup - (char *)d));
|
||||
d->hdr.bestfree[0].length = cpu_to_be16(t);
|
||||
dup->length = cpu_to_be16(t);
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(dup) = cpu_to_be16((char *)dup - (char *)d);
|
||||
/*
|
||||
* Log it and return it.
|
||||
*/
|
||||
@ -453,8 +455,8 @@ xfs_dir2_data_log_entry(
|
||||
xfs_dir2_data_t *d; /* data block pointer */
|
||||
|
||||
d = bp->data;
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
|
||||
INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
|
||||
be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d),
|
||||
(uint)((char *)(XFS_DIR2_DATA_ENTRY_TAG_P(dep) + 1) -
|
||||
(char *)d - 1));
|
||||
@ -471,8 +473,8 @@ xfs_dir2_data_log_header(
|
||||
xfs_dir2_data_t *d; /* data block pointer */
|
||||
|
||||
d = bp->data;
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
|
||||
INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
|
||||
be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d),
|
||||
(uint)(sizeof(d->hdr) - 1));
|
||||
}
|
||||
@ -489,8 +491,8 @@ xfs_dir2_data_log_unused(
|
||||
xfs_dir2_data_t *d; /* data block pointer */
|
||||
|
||||
d = bp->data;
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
|
||||
INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
|
||||
be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
/*
|
||||
* Log the first part of the unused entry.
|
||||
*/
|
||||
@ -533,12 +535,12 @@ xfs_dir2_data_make_free(
|
||||
/*
|
||||
* Figure out where the end of the data area is.
|
||||
*/
|
||||
if (INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC)
|
||||
if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC)
|
||||
endptr = (char *)d + mp->m_dirblksize;
|
||||
else {
|
||||
xfs_dir2_block_tail_t *btp; /* block tail */
|
||||
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d);
|
||||
endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp);
|
||||
}
|
||||
@ -547,11 +549,11 @@ xfs_dir2_data_make_free(
|
||||
* the previous entry and see if it's free.
|
||||
*/
|
||||
if (offset > sizeof(d->hdr)) {
|
||||
xfs_dir2_data_off_t *tagp; /* tag just before us */
|
||||
__be16 *tagp; /* tag just before us */
|
||||
|
||||
tagp = (xfs_dir2_data_off_t *)((char *)d + offset) - 1;
|
||||
prevdup = (xfs_dir2_data_unused_t *)((char *)d + INT_GET(*tagp, ARCH_CONVERT));
|
||||
if (INT_GET(prevdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG)
|
||||
tagp = (__be16 *)((char *)d + offset) - 1;
|
||||
prevdup = (xfs_dir2_data_unused_t *)((char *)d + be16_to_cpu(*tagp));
|
||||
if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
|
||||
prevdup = NULL;
|
||||
} else
|
||||
prevdup = NULL;
|
||||
@ -562,7 +564,7 @@ xfs_dir2_data_make_free(
|
||||
if ((char *)d + offset + len < endptr) {
|
||||
postdup =
|
||||
(xfs_dir2_data_unused_t *)((char *)d + offset + len);
|
||||
if (INT_GET(postdup->freetag, ARCH_CONVERT) != XFS_DIR2_DATA_FREE_TAG)
|
||||
if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
|
||||
postdup = NULL;
|
||||
} else
|
||||
postdup = NULL;
|
||||
@ -586,13 +588,13 @@ xfs_dir2_data_make_free(
|
||||
* since the third bestfree is there, there might be more
|
||||
* entries.
|
||||
*/
|
||||
needscan = d->hdr.bestfree[2].length;
|
||||
needscan = (d->hdr.bestfree[2].length != 0);
|
||||
/*
|
||||
* Fix up the new big freespace.
|
||||
*/
|
||||
INT_MOD(prevdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT));
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)((char *)prevdup - (char *)d));
|
||||
be16_add(&prevdup->length, len + be16_to_cpu(postdup->length));
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup) =
|
||||
cpu_to_be16((char *)prevdup - (char *)d);
|
||||
xfs_dir2_data_log_unused(tp, bp, prevdup);
|
||||
if (!needscan) {
|
||||
/*
|
||||
@ -614,7 +616,7 @@ xfs_dir2_data_make_free(
|
||||
*/
|
||||
dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp);
|
||||
ASSERT(dfp == &d->hdr.bestfree[0]);
|
||||
ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(prevdup->length, ARCH_CONVERT));
|
||||
ASSERT(dfp->length == prevdup->length);
|
||||
ASSERT(!dfp[1].length);
|
||||
ASSERT(!dfp[2].length);
|
||||
}
|
||||
@ -624,9 +626,9 @@ xfs_dir2_data_make_free(
|
||||
*/
|
||||
else if (prevdup) {
|
||||
dfp = xfs_dir2_data_freefind(d, prevdup);
|
||||
INT_MOD(prevdup->length, ARCH_CONVERT, len);
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)((char *)prevdup - (char *)d));
|
||||
be16_add(&prevdup->length, len);
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(prevdup) =
|
||||
cpu_to_be16((char *)prevdup - (char *)d);
|
||||
xfs_dir2_data_log_unused(tp, bp, prevdup);
|
||||
/*
|
||||
* If the previous entry was in the table, the new entry
|
||||
@ -640,8 +642,10 @@ xfs_dir2_data_make_free(
|
||||
/*
|
||||
* Otherwise we need a scan if the new entry is big enough.
|
||||
*/
|
||||
else
|
||||
needscan = INT_GET(prevdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT);
|
||||
else {
|
||||
needscan = be16_to_cpu(prevdup->length) >
|
||||
be16_to_cpu(d->hdr.bestfree[2].length);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The following entry is free, merge with it.
|
||||
@ -649,10 +653,10 @@ xfs_dir2_data_make_free(
|
||||
else if (postdup) {
|
||||
dfp = xfs_dir2_data_freefind(d, postdup);
|
||||
newdup = (xfs_dir2_data_unused_t *)((char *)d + offset);
|
||||
INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
|
||||
INT_SET(newdup->length, ARCH_CONVERT, len + INT_GET(postdup->length, ARCH_CONVERT));
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)((char *)newdup - (char *)d));
|
||||
newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
|
||||
newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)d);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
/*
|
||||
* If the following entry was in the table, the new entry
|
||||
@ -666,18 +670,20 @@ xfs_dir2_data_make_free(
|
||||
/*
|
||||
* Otherwise we need a scan if the new entry is big enough.
|
||||
*/
|
||||
else
|
||||
needscan = INT_GET(newdup->length, ARCH_CONVERT) > INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT);
|
||||
else {
|
||||
needscan = be16_to_cpu(newdup->length) >
|
||||
be16_to_cpu(d->hdr.bestfree[2].length);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Neither neighbor is free. Make a new entry.
|
||||
*/
|
||||
else {
|
||||
newdup = (xfs_dir2_data_unused_t *)((char *)d + offset);
|
||||
INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
|
||||
INT_SET(newdup->length, ARCH_CONVERT, len);
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)((char *)newdup - (char *)d));
|
||||
newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
|
||||
newdup->length = cpu_to_be16(len);
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)d);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
(void)xfs_dir2_data_freeinsert(d, newdup, needlogp);
|
||||
}
|
||||
@ -707,18 +713,18 @@ xfs_dir2_data_use_free(
|
||||
int oldlen; /* old unused entry's length */
|
||||
|
||||
d = bp->data;
|
||||
ASSERT(INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC ||
|
||||
INT_GET(d->hdr.magic, ARCH_CONVERT) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG);
|
||||
ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC ||
|
||||
be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC);
|
||||
ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG);
|
||||
ASSERT(offset >= (char *)dup - (char *)d);
|
||||
ASSERT(offset + len <= (char *)dup + INT_GET(dup->length, ARCH_CONVERT) - (char *)d);
|
||||
ASSERT((char *)dup - (char *)d == INT_GET(*XFS_DIR2_DATA_UNUSED_TAG_P(dup), ARCH_CONVERT));
|
||||
ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d);
|
||||
ASSERT((char *)dup - (char *)d == be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup)));
|
||||
/*
|
||||
* Look up the entry in the bestfree table.
|
||||
*/
|
||||
dfp = xfs_dir2_data_freefind(d, dup);
|
||||
oldlen = INT_GET(dup->length, ARCH_CONVERT);
|
||||
ASSERT(dfp || oldlen <= INT_GET(d->hdr.bestfree[2].length, ARCH_CONVERT));
|
||||
oldlen = be16_to_cpu(dup->length);
|
||||
ASSERT(dfp || oldlen <= be16_to_cpu(d->hdr.bestfree[2].length));
|
||||
/*
|
||||
* Check for alignment with front and back of the entry.
|
||||
*/
|
||||
@ -732,7 +738,7 @@ xfs_dir2_data_use_free(
|
||||
*/
|
||||
if (matchfront && matchback) {
|
||||
if (dfp) {
|
||||
needscan = d->hdr.bestfree[2].offset;
|
||||
needscan = (d->hdr.bestfree[2].offset != 0);
|
||||
if (!needscan)
|
||||
xfs_dir2_data_freeremove(d, dfp, needlogp);
|
||||
}
|
||||
@ -743,10 +749,10 @@ xfs_dir2_data_use_free(
|
||||
*/
|
||||
else if (matchfront) {
|
||||
newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len);
|
||||
INT_SET(newdup->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
|
||||
INT_SET(newdup->length, ARCH_CONVERT, oldlen - len);
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)((char *)newdup - (char *)d));
|
||||
newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
|
||||
newdup->length = cpu_to_be16(oldlen - len);
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)d);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
/*
|
||||
* If it was in the table, remove it and add the new one.
|
||||
@ -755,8 +761,8 @@ xfs_dir2_data_use_free(
|
||||
xfs_dir2_data_freeremove(d, dfp, needlogp);
|
||||
dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp);
|
||||
ASSERT(dfp != NULL);
|
||||
ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(newdup->length, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) == (char *)newdup - (char *)d);
|
||||
ASSERT(dfp->length == newdup->length);
|
||||
ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d);
|
||||
/*
|
||||
* If we got inserted at the last slot,
|
||||
* that means we don't know if there was a better
|
||||
@ -771,10 +777,9 @@ xfs_dir2_data_use_free(
|
||||
*/
|
||||
else if (matchback) {
|
||||
newdup = dup;
|
||||
INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t)
|
||||
(((char *)d + offset) - (char *)newdup));
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)((char *)newdup - (char *)d));
|
||||
newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup);
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)d);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
/*
|
||||
* If it was in the table, remove it and add the new one.
|
||||
@ -783,8 +788,8 @@ xfs_dir2_data_use_free(
|
||||
xfs_dir2_data_freeremove(d, dfp, needlogp);
|
||||
dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp);
|
||||
ASSERT(dfp != NULL);
|
||||
ASSERT(INT_GET(dfp->length, ARCH_CONVERT) == INT_GET(newdup->length, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(dfp->offset, ARCH_CONVERT) == (char *)newdup - (char *)d);
|
||||
ASSERT(dfp->length == newdup->length);
|
||||
ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d);
|
||||
/*
|
||||
* If we got inserted at the last slot,
|
||||
* that means we don't know if there was a better
|
||||
@ -799,16 +804,15 @@ xfs_dir2_data_use_free(
|
||||
*/
|
||||
else {
|
||||
newdup = dup;
|
||||
INT_SET(newdup->length, ARCH_CONVERT, (xfs_dir2_data_off_t)
|
||||
(((char *)d + offset) - (char *)newdup));
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)((char *)newdup - (char *)d));
|
||||
newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup);
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(newdup) =
|
||||
cpu_to_be16((char *)newdup - (char *)d);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup);
|
||||
newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len);
|
||||
INT_SET(newdup2->freetag, ARCH_CONVERT, XFS_DIR2_DATA_FREE_TAG);
|
||||
INT_SET(newdup2->length, ARCH_CONVERT, oldlen - len - INT_GET(newdup->length, ARCH_CONVERT));
|
||||
INT_SET(*XFS_DIR2_DATA_UNUSED_TAG_P(newdup2), ARCH_CONVERT,
|
||||
(xfs_dir2_data_off_t)((char *)newdup2 - (char *)d));
|
||||
newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
|
||||
newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length));
|
||||
*XFS_DIR2_DATA_UNUSED_TAG_P(newdup2) =
|
||||
cpu_to_be16((char *)newdup2 - (char *)d);
|
||||
xfs_dir2_data_log_unused(tp, bp, newdup2);
|
||||
/*
|
||||
* If the old entry was in the table, we need to scan
|
||||
@ -819,7 +823,7 @@ xfs_dir2_data_use_free(
|
||||
* the 2 new will work.
|
||||
*/
|
||||
if (dfp) {
|
||||
needscan = d->hdr.bestfree[2].length;
|
||||
needscan = (d->hdr.bestfree[2].length != 0);
|
||||
if (!needscan) {
|
||||
xfs_dir2_data_freeremove(d, dfp, needlogp);
|
||||
(void)xfs_dir2_data_freeinsert(d, newdup,
|
||||
|
@ -65,8 +65,8 @@ struct xfs_trans;
|
||||
* The freespace will be formatted as a xfs_dir2_data_unused_t.
|
||||
*/
|
||||
typedef struct xfs_dir2_data_free {
|
||||
xfs_dir2_data_off_t offset; /* start of freespace */
|
||||
xfs_dir2_data_off_t length; /* length of freespace */
|
||||
__be16 offset; /* start of freespace */
|
||||
__be16 length; /* length of freespace */
|
||||
} xfs_dir2_data_free_t;
|
||||
|
||||
/*
|
||||
@ -75,7 +75,7 @@ typedef struct xfs_dir2_data_free {
|
||||
* The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
|
||||
*/
|
||||
typedef struct xfs_dir2_data_hdr {
|
||||
__uint32_t magic; /* XFS_DIR2_DATA_MAGIC */
|
||||
__be32 magic; /* XFS_DIR2_DATA_MAGIC */
|
||||
/* or XFS_DIR2_BLOCK_MAGIC */
|
||||
xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
|
||||
} xfs_dir2_data_hdr_t;
|
||||
@ -97,10 +97,10 @@ typedef struct xfs_dir2_data_entry {
|
||||
* Tag appears as the last 2 bytes.
|
||||
*/
|
||||
typedef struct xfs_dir2_data_unused {
|
||||
__uint16_t freetag; /* XFS_DIR2_DATA_FREE_TAG */
|
||||
xfs_dir2_data_off_t length; /* total free length */
|
||||
__be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */
|
||||
__be16 length; /* total free length */
|
||||
/* variable offset */
|
||||
xfs_dir2_data_off_t tag; /* starting offset of us */
|
||||
__be16 tag; /* starting offset of us */
|
||||
} xfs_dir2_data_unused_t;
|
||||
|
||||
typedef union {
|
||||
@ -134,12 +134,11 @@ static inline int xfs_dir2_data_entsize(int n)
|
||||
* Pointer to an entry's tag word.
|
||||
*/
|
||||
#define XFS_DIR2_DATA_ENTRY_TAG_P(dep) xfs_dir2_data_entry_tag_p(dep)
|
||||
static inline xfs_dir2_data_off_t *
|
||||
static inline __be16 *
|
||||
xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep)
|
||||
{
|
||||
return (xfs_dir2_data_off_t *) \
|
||||
((char *)(dep) + XFS_DIR2_DATA_ENTSIZE((dep)->namelen) - \
|
||||
(uint)sizeof(xfs_dir2_data_off_t));
|
||||
return (__be16 *)((char *)dep +
|
||||
XFS_DIR2_DATA_ENTSIZE(dep->namelen) - sizeof(__be16));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -147,12 +146,11 @@ xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep)
|
||||
*/
|
||||
#define XFS_DIR2_DATA_UNUSED_TAG_P(dup) \
|
||||
xfs_dir2_data_unused_tag_p(dup)
|
||||
static inline xfs_dir2_data_off_t *
|
||||
static inline __be16 *
|
||||
xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup)
|
||||
{
|
||||
return (xfs_dir2_data_off_t *) \
|
||||
((char *)(dup) + INT_GET((dup)->length, ARCH_CONVERT) \
|
||||
- (uint)sizeof(xfs_dir2_data_off_t));
|
||||
return (__be16 *)((char *)dup +
|
||||
be16_to_cpu(dup->length) - sizeof(__be16));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -66,7 +66,7 @@ xfs_dir2_block_to_leaf(
|
||||
xfs_da_args_t *args, /* operation arguments */
|
||||
xfs_dabuf_t *dbp) /* input block's buffer */
|
||||
{
|
||||
xfs_dir2_data_off_t *bestsp; /* leaf's bestsp entries */
|
||||
__be16 *bestsp; /* leaf's bestsp entries */
|
||||
xfs_dablk_t blkno; /* leaf block's bno */
|
||||
xfs_dir2_block_t *block; /* block structure */
|
||||
xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */
|
||||
@ -111,14 +111,14 @@ xfs_dir2_block_to_leaf(
|
||||
/*
|
||||
* Set the counts in the leaf header.
|
||||
*/
|
||||
INT_COPY(leaf->hdr.count, btp->count, ARCH_CONVERT); /* INT_: type change */
|
||||
INT_COPY(leaf->hdr.stale, btp->stale, ARCH_CONVERT); /* INT_: type change */
|
||||
leaf->hdr.count = cpu_to_be16(be32_to_cpu(btp->count));
|
||||
leaf->hdr.stale = cpu_to_be16(be32_to_cpu(btp->stale));
|
||||
/*
|
||||
* Could compact these but I think we always do the conversion
|
||||
* after squeezing out stale entries.
|
||||
*/
|
||||
memcpy(leaf->ents, blp, INT_GET(btp->count, ARCH_CONVERT) * sizeof(xfs_dir2_leaf_entry_t));
|
||||
xfs_dir2_leaf_log_ents(tp, lbp, 0, INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1);
|
||||
memcpy(leaf->ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t));
|
||||
xfs_dir2_leaf_log_ents(tp, lbp, 0, be16_to_cpu(leaf->hdr.count) - 1);
|
||||
needscan = 0;
|
||||
needlog = 1;
|
||||
/*
|
||||
@ -133,7 +133,7 @@ xfs_dir2_block_to_leaf(
|
||||
/*
|
||||
* Fix up the block header, make it a data block.
|
||||
*/
|
||||
INT_SET(block->hdr.magic, ARCH_CONVERT, XFS_DIR2_DATA_MAGIC);
|
||||
block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
|
||||
if (needscan)
|
||||
xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog,
|
||||
NULL);
|
||||
@ -141,9 +141,9 @@ xfs_dir2_block_to_leaf(
|
||||
* Set up leaf tail and bests table.
|
||||
*/
|
||||
ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
|
||||
INT_SET(ltp->bestcount, ARCH_CONVERT, 1);
|
||||
ltp->bestcount = cpu_to_be32(1);
|
||||
bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
|
||||
INT_COPY(bestsp[0], block->hdr.bestfree[0].length, ARCH_CONVERT);
|
||||
bestsp[0] = block->hdr.bestfree[0].length;
|
||||
/*
|
||||
* Log the data header and leaf bests table.
|
||||
*/
|
||||
@ -163,7 +163,7 @@ int /* error */
|
||||
xfs_dir2_leaf_addname(
|
||||
xfs_da_args_t *args) /* operation arguments */
|
||||
{
|
||||
xfs_dir2_data_off_t *bestsp; /* freespace table in leaf */
|
||||
__be16 *bestsp; /* freespace table in leaf */
|
||||
int compact; /* need to compact leaves */
|
||||
xfs_dir2_data_t *data; /* data block structure */
|
||||
xfs_dabuf_t *dbp; /* data block buffer */
|
||||
@ -187,7 +187,7 @@ xfs_dir2_leaf_addname(
|
||||
int needbytes; /* leaf block bytes needed */
|
||||
int needlog; /* need to log data header */
|
||||
int needscan; /* need to rescan data free */
|
||||
xfs_dir2_data_off_t *tagp; /* end of data entry */
|
||||
__be16 *tagp; /* end of data entry */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
xfs_dir2_db_t use_block; /* data block number */
|
||||
|
||||
@ -222,14 +222,14 @@ xfs_dir2_leaf_addname(
|
||||
* in a data block, improving the lookup of those entries.
|
||||
*/
|
||||
for (use_block = -1, lep = &leaf->ents[index];
|
||||
index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval;
|
||||
index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval;
|
||||
index++, lep++) {
|
||||
if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
|
||||
if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
|
||||
continue;
|
||||
i = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
|
||||
ASSERT(i < INT_GET(ltp->bestcount, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF);
|
||||
if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) {
|
||||
i = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
|
||||
ASSERT(i < be32_to_cpu(ltp->bestcount));
|
||||
ASSERT(be16_to_cpu(bestsp[i]) != NULLDATAOFF);
|
||||
if (be16_to_cpu(bestsp[i]) >= length) {
|
||||
use_block = i;
|
||||
break;
|
||||
}
|
||||
@ -238,13 +238,13 @@ xfs_dir2_leaf_addname(
|
||||
* Didn't find a block yet, linear search all the data blocks.
|
||||
*/
|
||||
if (use_block == -1) {
|
||||
for (i = 0; i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++) {
|
||||
for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) {
|
||||
/*
|
||||
* Remember a block we see that's missing.
|
||||
*/
|
||||
if (INT_GET(bestsp[i], ARCH_CONVERT) == NULLDATAOFF && use_block == -1)
|
||||
if (be16_to_cpu(bestsp[i]) == NULLDATAOFF && use_block == -1)
|
||||
use_block = i;
|
||||
else if (INT_GET(bestsp[i], ARCH_CONVERT) >= length) {
|
||||
else if (be16_to_cpu(bestsp[i]) >= length) {
|
||||
use_block = i;
|
||||
break;
|
||||
}
|
||||
@ -260,21 +260,21 @@ xfs_dir2_leaf_addname(
|
||||
* Now kill use_block if it refers to a missing block, so we
|
||||
* can use it as an indication of allocation needed.
|
||||
*/
|
||||
if (use_block != -1 && INT_GET(bestsp[use_block], ARCH_CONVERT) == NULLDATAOFF)
|
||||
if (use_block != -1 && be16_to_cpu(bestsp[use_block]) == NULLDATAOFF)
|
||||
use_block = -1;
|
||||
/*
|
||||
* If we don't have enough free bytes but we can make enough
|
||||
* by compacting out stale entries, we'll do that.
|
||||
*/
|
||||
if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] < needbytes &&
|
||||
INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1) {
|
||||
if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] < needbytes &&
|
||||
be16_to_cpu(leaf->hdr.stale) > 1) {
|
||||
compact = 1;
|
||||
}
|
||||
/*
|
||||
* Otherwise if we don't have enough free bytes we need to
|
||||
* convert to node form.
|
||||
*/
|
||||
else if ((char *)bestsp - (char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] <
|
||||
else if ((char *)bestsp - (char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <
|
||||
needbytes) {
|
||||
/*
|
||||
* Just checking or no space reservation, give up.
|
||||
@ -330,8 +330,8 @@ xfs_dir2_leaf_addname(
|
||||
* There are stale entries, so we'll need log-low and log-high
|
||||
* impossibly bad values later.
|
||||
*/
|
||||
else if (INT_GET(leaf->hdr.stale, ARCH_CONVERT)) {
|
||||
lfloglow = INT_GET(leaf->hdr.count, ARCH_CONVERT);
|
||||
else if (be16_to_cpu(leaf->hdr.stale)) {
|
||||
lfloglow = be16_to_cpu(leaf->hdr.count);
|
||||
lfloghigh = -1;
|
||||
}
|
||||
/*
|
||||
@ -358,13 +358,13 @@ xfs_dir2_leaf_addname(
|
||||
* If we're adding a new data block on the end we need to
|
||||
* extend the bests table. Copy it up one entry.
|
||||
*/
|
||||
if (use_block >= INT_GET(ltp->bestcount, ARCH_CONVERT)) {
|
||||
if (use_block >= be32_to_cpu(ltp->bestcount)) {
|
||||
bestsp--;
|
||||
memmove(&bestsp[0], &bestsp[1],
|
||||
INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(bestsp[0]));
|
||||
INT_MOD(ltp->bestcount, ARCH_CONVERT, +1);
|
||||
be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
|
||||
be32_add(<p->bestcount, 1);
|
||||
xfs_dir2_leaf_log_tail(tp, lbp);
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
}
|
||||
/*
|
||||
* If we're filling in a previously empty block just log it.
|
||||
@ -372,7 +372,7 @@ xfs_dir2_leaf_addname(
|
||||
else
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
|
||||
data = dbp->data;
|
||||
INT_COPY(bestsp[use_block], data->hdr.bestfree[0].length, ARCH_CONVERT);
|
||||
bestsp[use_block] = data->hdr.bestfree[0].length;
|
||||
grown = 1;
|
||||
}
|
||||
/*
|
||||
@ -394,8 +394,8 @@ xfs_dir2_leaf_addname(
|
||||
* Point to the biggest freespace in our data block.
|
||||
*/
|
||||
dup = (xfs_dir2_data_unused_t *)
|
||||
((char *)data + INT_GET(data->hdr.bestfree[0].offset, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(dup->length, ARCH_CONVERT) >= length);
|
||||
((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset));
|
||||
ASSERT(be16_to_cpu(dup->length) >= length);
|
||||
needscan = needlog = 0;
|
||||
/*
|
||||
* Mark the initial part of our freespace in use for the new entry.
|
||||
@ -411,7 +411,7 @@ xfs_dir2_leaf_addname(
|
||||
dep->namelen = args->namelen;
|
||||
memcpy(dep->name, args->name, dep->namelen);
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)data));
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)data);
|
||||
/*
|
||||
* Need to scan fix up the bestfree table.
|
||||
*/
|
||||
@ -427,8 +427,8 @@ xfs_dir2_leaf_addname(
|
||||
* If the bests table needs to be changed, do it.
|
||||
* Log the change unless we've already done that.
|
||||
*/
|
||||
if (INT_GET(bestsp[use_block], ARCH_CONVERT) != INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) {
|
||||
INT_COPY(bestsp[use_block], data->hdr.bestfree[0].length, ARCH_CONVERT);
|
||||
if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(data->hdr.bestfree[0].length)) {
|
||||
bestsp[use_block] = data->hdr.bestfree[0].length;
|
||||
if (!grown)
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
|
||||
}
|
||||
@ -440,15 +440,15 @@ xfs_dir2_leaf_addname(
|
||||
/*
|
||||
* lep is still good as the index leaf entry.
|
||||
*/
|
||||
if (index < INT_GET(leaf->hdr.count, ARCH_CONVERT))
|
||||
if (index < be16_to_cpu(leaf->hdr.count))
|
||||
memmove(lep + 1, lep,
|
||||
(INT_GET(leaf->hdr.count, ARCH_CONVERT) - index) * sizeof(*lep));
|
||||
(be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
|
||||
/*
|
||||
* Record low and high logging indices for the leaf.
|
||||
*/
|
||||
lfloglow = index;
|
||||
lfloghigh = INT_GET(leaf->hdr.count, ARCH_CONVERT);
|
||||
INT_MOD(leaf->hdr.count, ARCH_CONVERT, +1);
|
||||
lfloghigh = be16_to_cpu(leaf->hdr.count);
|
||||
be16_add(&leaf->hdr.count, 1);
|
||||
}
|
||||
/*
|
||||
* There are stale entries.
|
||||
@ -468,7 +468,7 @@ xfs_dir2_leaf_addname(
|
||||
*/
|
||||
for (lowstale = index - 1;
|
||||
lowstale >= 0 &&
|
||||
INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) !=
|
||||
be32_to_cpu(leaf->ents[lowstale].address) !=
|
||||
XFS_DIR2_NULL_DATAPTR;
|
||||
lowstale--)
|
||||
continue;
|
||||
@ -478,8 +478,8 @@ xfs_dir2_leaf_addname(
|
||||
* lowstale entry would be better.
|
||||
*/
|
||||
for (highstale = index;
|
||||
highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) &&
|
||||
INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) !=
|
||||
highstale < be16_to_cpu(leaf->hdr.count) &&
|
||||
be32_to_cpu(leaf->ents[highstale].address) !=
|
||||
XFS_DIR2_NULL_DATAPTR &&
|
||||
(lowstale < 0 ||
|
||||
index - lowstale - 1 >= highstale - index);
|
||||
@ -490,10 +490,10 @@ xfs_dir2_leaf_addname(
|
||||
* If the low one is better, use it.
|
||||
*/
|
||||
if (lowstale >= 0 &&
|
||||
(highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
|
||||
(highstale == be16_to_cpu(leaf->hdr.count) ||
|
||||
index - lowstale - 1 < highstale - index)) {
|
||||
ASSERT(index - lowstale - 1 >= 0);
|
||||
ASSERT(INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) ==
|
||||
ASSERT(be32_to_cpu(leaf->ents[lowstale].address) ==
|
||||
XFS_DIR2_NULL_DATAPTR);
|
||||
/*
|
||||
* Copy entries up to cover the stale entry
|
||||
@ -512,7 +512,7 @@ xfs_dir2_leaf_addname(
|
||||
*/
|
||||
else {
|
||||
ASSERT(highstale - index >= 0);
|
||||
ASSERT(INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) ==
|
||||
ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
|
||||
XFS_DIR2_NULL_DATAPTR);
|
||||
/*
|
||||
* Copy entries down to copver the stale entry
|
||||
@ -526,13 +526,14 @@ xfs_dir2_leaf_addname(
|
||||
lfloglow = MIN(index, lfloglow);
|
||||
lfloghigh = MAX(highstale, lfloghigh);
|
||||
}
|
||||
INT_MOD(leaf->hdr.stale, ARCH_CONVERT, -1);
|
||||
be16_add(&leaf->hdr.stale, -1);
|
||||
}
|
||||
/*
|
||||
* Fill in the new leaf entry.
|
||||
*/
|
||||
INT_SET(lep->hashval, ARCH_CONVERT, args->hashval);
|
||||
INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_DB_OFF_TO_DATAPTR(mp, use_block, INT_GET(*tagp, ARCH_CONVERT)));
|
||||
lep->hashval = cpu_to_be32(args->hashval);
|
||||
lep->address = cpu_to_be32(XFS_DIR2_DB_OFF_TO_DATAPTR(mp, use_block,
|
||||
be16_to_cpu(*tagp)));
|
||||
/*
|
||||
* Log the leaf fields and give up the buffers.
|
||||
*/
|
||||
@ -563,30 +564,30 @@ xfs_dir2_leaf_check(
|
||||
|
||||
leaf = bp->data;
|
||||
mp = dp->i_mount;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC);
|
||||
/*
|
||||
* This value is not restrictive enough.
|
||||
* Should factor in the size of the bests table as well.
|
||||
* We can deduce a value for that from di_size.
|
||||
*/
|
||||
ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) <= XFS_DIR2_MAX_LEAF_ENTS(mp));
|
||||
ASSERT(be16_to_cpu(leaf->hdr.count) <= XFS_DIR2_MAX_LEAF_ENTS(mp));
|
||||
ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
|
||||
/*
|
||||
* Leaves and bests don't overlap.
|
||||
*/
|
||||
ASSERT((char *)&leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT)] <=
|
||||
ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <=
|
||||
(char *)XFS_DIR2_LEAF_BESTS_P(ltp));
|
||||
/*
|
||||
* Check hash value order, count stale entries.
|
||||
*/
|
||||
for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) {
|
||||
if (i + 1 < INT_GET(leaf->hdr.count, ARCH_CONVERT))
|
||||
ASSERT(INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) <=
|
||||
INT_GET(leaf->ents[i + 1].hashval, ARCH_CONVERT));
|
||||
if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
|
||||
for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
|
||||
if (i + 1 < be16_to_cpu(leaf->hdr.count))
|
||||
ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
|
||||
be32_to_cpu(leaf->ents[i + 1].hashval));
|
||||
if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR)
|
||||
stale++;
|
||||
}
|
||||
ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == stale);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
@ -611,8 +612,8 @@ xfs_dir2_leaf_compact(
|
||||
/*
|
||||
* Compress out the stale entries in place.
|
||||
*/
|
||||
for (from = to = 0, loglow = -1; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) {
|
||||
if (INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
|
||||
for (from = to = 0, loglow = -1; from < be16_to_cpu(leaf->hdr.count); from++) {
|
||||
if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR)
|
||||
continue;
|
||||
/*
|
||||
* Only actually copy the entries that are different.
|
||||
@ -627,8 +628,8 @@ xfs_dir2_leaf_compact(
|
||||
/*
|
||||
* Update and log the header, log the leaf entries.
|
||||
*/
|
||||
ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == from - to);
|
||||
INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(INT_GET(leaf->hdr.stale, ARCH_CONVERT)));
|
||||
ASSERT(be16_to_cpu(leaf->hdr.stale) == from - to);
|
||||
be16_add(&leaf->hdr.count, -(be16_to_cpu(leaf->hdr.stale)));
|
||||
leaf->hdr.stale = 0;
|
||||
xfs_dir2_leaf_log_header(args->trans, bp);
|
||||
if (loglow != -1)
|
||||
@ -662,14 +663,14 @@ xfs_dir2_leaf_compact_x1(
|
||||
int to; /* destination copy index */
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.stale) > 1);
|
||||
index = *indexp;
|
||||
/*
|
||||
* Find the first stale entry before our index, if any.
|
||||
*/
|
||||
for (lowstale = index - 1;
|
||||
lowstale >= 0 &&
|
||||
INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR;
|
||||
be32_to_cpu(leaf->ents[lowstale].address) != XFS_DIR2_NULL_DATAPTR;
|
||||
lowstale--)
|
||||
continue;
|
||||
/*
|
||||
@ -677,8 +678,8 @@ xfs_dir2_leaf_compact_x1(
|
||||
* Stop if the answer would be worse than lowstale.
|
||||
*/
|
||||
for (highstale = index;
|
||||
highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) &&
|
||||
INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) != XFS_DIR2_NULL_DATAPTR &&
|
||||
highstale < be16_to_cpu(leaf->hdr.count) &&
|
||||
be32_to_cpu(leaf->ents[highstale].address) != XFS_DIR2_NULL_DATAPTR &&
|
||||
(lowstale < 0 || index - lowstale > highstale - index);
|
||||
highstale++)
|
||||
continue;
|
||||
@ -686,7 +687,7 @@ xfs_dir2_leaf_compact_x1(
|
||||
* Pick the better of lowstale and highstale.
|
||||
*/
|
||||
if (lowstale >= 0 &&
|
||||
(highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
|
||||
(highstale == be16_to_cpu(leaf->hdr.count) ||
|
||||
index - lowstale <= highstale - index))
|
||||
keepstale = lowstale;
|
||||
else
|
||||
@ -695,14 +696,14 @@ xfs_dir2_leaf_compact_x1(
|
||||
* Copy the entries in place, removing all the stale entries
|
||||
* except keepstale.
|
||||
*/
|
||||
for (from = to = 0; from < INT_GET(leaf->hdr.count, ARCH_CONVERT); from++) {
|
||||
for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) {
|
||||
/*
|
||||
* Notice the new value of index.
|
||||
*/
|
||||
if (index == from)
|
||||
newindex = to;
|
||||
if (from != keepstale &&
|
||||
INT_GET(leaf->ents[from].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR) {
|
||||
be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) {
|
||||
if (from == to)
|
||||
*lowlogp = to;
|
||||
continue;
|
||||
@ -730,8 +731,8 @@ xfs_dir2_leaf_compact_x1(
|
||||
/*
|
||||
* Adjust the leaf header values.
|
||||
*/
|
||||
INT_MOD(leaf->hdr.count, ARCH_CONVERT, -(from - to));
|
||||
INT_SET(leaf->hdr.stale, ARCH_CONVERT, 1);
|
||||
be16_add(&leaf->hdr.count, -(from - to));
|
||||
leaf->hdr.stale = cpu_to_be16(1);
|
||||
/*
|
||||
* Remember the low/high stale value only in the "right"
|
||||
* direction.
|
||||
@ -739,8 +740,8 @@ xfs_dir2_leaf_compact_x1(
|
||||
if (lowstale >= newindex)
|
||||
lowstale = -1;
|
||||
else
|
||||
highstale = INT_GET(leaf->hdr.count, ARCH_CONVERT);
|
||||
*highlogp = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1;
|
||||
highstale = be16_to_cpu(leaf->hdr.count);
|
||||
*highlogp = be16_to_cpu(leaf->hdr.count) - 1;
|
||||
*lowstalep = lowstale;
|
||||
*highstalep = highstale;
|
||||
}
|
||||
@ -766,7 +767,7 @@ xfs_dir2_leaf_getdents(
|
||||
xfs_dir2_data_entry_t *dep; /* data entry */
|
||||
xfs_dir2_data_unused_t *dup; /* unused entry */
|
||||
int eof; /* reached end of directory */
|
||||
int error=0; /* error return value */
|
||||
int error = 0; /* error return value */
|
||||
int i; /* temporary loop index */
|
||||
int j; /* temporary loop index */
|
||||
int length; /* temporary length value */
|
||||
@ -778,8 +779,8 @@ xfs_dir2_leaf_getdents(
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
xfs_dir2_off_t newoff; /* new curoff after new blk */
|
||||
int nmap; /* mappings to ask xfs_bmapi */
|
||||
xfs_dir2_put_args_t p; /* formatting arg bundle */
|
||||
char *ptr=NULL; /* pointer to current data */
|
||||
xfs_dir2_put_args_t *p; /* formatting arg bundle */
|
||||
char *ptr = NULL; /* pointer to current data */
|
||||
int ra_current; /* number of read-ahead blks */
|
||||
int ra_index; /* *map index for read-ahead */
|
||||
int ra_offset; /* map entry offset for ra */
|
||||
@ -797,9 +798,10 @@ xfs_dir2_leaf_getdents(
|
||||
/*
|
||||
* Setup formatting arguments.
|
||||
*/
|
||||
p.dbp = dbp;
|
||||
p.put = put;
|
||||
p.uio = uio;
|
||||
p = kmem_alloc(sizeof(*p), KM_SLEEP);
|
||||
p->dbp = dbp;
|
||||
p->put = put;
|
||||
p->uio = uio;
|
||||
/*
|
||||
* Set up to bmap a number of blocks based on the caller's
|
||||
* buffer size, the directory block size, and the filesystem
|
||||
@ -1046,11 +1048,10 @@ xfs_dir2_leaf_getdents(
|
||||
while ((char *)ptr - (char *)data < byteoff) {
|
||||
dup = (xfs_dir2_data_unused_t *)ptr;
|
||||
|
||||
if (INT_GET(dup->freetag, ARCH_CONVERT)
|
||||
if (be16_to_cpu(dup->freetag)
|
||||
== XFS_DIR2_DATA_FREE_TAG) {
|
||||
|
||||
length = INT_GET(dup->length,
|
||||
ARCH_CONVERT);
|
||||
length = be16_to_cpu(dup->length);
|
||||
ptr += length;
|
||||
continue;
|
||||
}
|
||||
@ -1079,9 +1080,8 @@ xfs_dir2_leaf_getdents(
|
||||
/*
|
||||
* No, it's unused, skip over it.
|
||||
*/
|
||||
if (INT_GET(dup->freetag, ARCH_CONVERT)
|
||||
== XFS_DIR2_DATA_FREE_TAG) {
|
||||
length = INT_GET(dup->length, ARCH_CONVERT);
|
||||
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
length = be16_to_cpu(dup->length);
|
||||
ptr += length;
|
||||
curoff += length;
|
||||
continue;
|
||||
@ -1092,24 +1092,24 @@ xfs_dir2_leaf_getdents(
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)ptr;
|
||||
|
||||
p.namelen = dep->namelen;
|
||||
p->namelen = dep->namelen;
|
||||
|
||||
length = XFS_DIR2_DATA_ENTSIZE(p.namelen);
|
||||
length = XFS_DIR2_DATA_ENTSIZE(p->namelen);
|
||||
|
||||
p.cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
|
||||
p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length);
|
||||
|
||||
p.ino = INT_GET(dep->inumber, ARCH_CONVERT);
|
||||
p->ino = INT_GET(dep->inumber, ARCH_CONVERT);
|
||||
#if XFS_BIG_INUMS
|
||||
p.ino += mp->m_inoadd;
|
||||
p->ino += mp->m_inoadd;
|
||||
#endif
|
||||
p.name = (char *)dep->name;
|
||||
p->name = (char *)dep->name;
|
||||
|
||||
error = p.put(&p);
|
||||
error = p->put(p);
|
||||
|
||||
/*
|
||||
* Won't fit. Return to caller.
|
||||
*/
|
||||
if (!p.done) {
|
||||
if (!p->done) {
|
||||
eof = 0;
|
||||
break;
|
||||
}
|
||||
@ -1129,6 +1129,7 @@ xfs_dir2_leaf_getdents(
|
||||
else
|
||||
uio->uio_offset = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff);
|
||||
kmem_free(map, map_size * sizeof(*map));
|
||||
kmem_free(p, sizeof(*p));
|
||||
if (bp)
|
||||
xfs_da_brelse(tp, bp);
|
||||
return error;
|
||||
@ -1171,7 +1172,7 @@ xfs_dir2_leaf_init(
|
||||
/*
|
||||
* Initialize the header.
|
||||
*/
|
||||
INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, magic);
|
||||
leaf->hdr.info.magic = cpu_to_be16(magic);
|
||||
leaf->hdr.info.forw = 0;
|
||||
leaf->hdr.info.back = 0;
|
||||
leaf->hdr.count = 0;
|
||||
@ -1201,13 +1202,13 @@ xfs_dir2_leaf_log_bests(
|
||||
int first, /* first entry to log */
|
||||
int last) /* last entry to log */
|
||||
{
|
||||
xfs_dir2_data_off_t *firstb; /* pointer to first entry */
|
||||
xfs_dir2_data_off_t *lastb; /* pointer to last entry */
|
||||
__be16 *firstb; /* pointer to first entry */
|
||||
__be16 *lastb; /* pointer to last entry */
|
||||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC);
|
||||
ltp = XFS_DIR2_LEAF_TAIL_P(tp->t_mountp, leaf);
|
||||
firstb = XFS_DIR2_LEAF_BESTS_P(ltp) + first;
|
||||
lastb = XFS_DIR2_LEAF_BESTS_P(ltp) + last;
|
||||
@ -1230,8 +1231,8 @@ xfs_dir2_leaf_log_ents(
|
||||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC ||
|
||||
INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC ||
|
||||
be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
firstlep = &leaf->ents[first];
|
||||
lastlep = &leaf->ents[last];
|
||||
xfs_da_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf),
|
||||
@ -1249,8 +1250,8 @@ xfs_dir2_leaf_log_header(
|
||||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC ||
|
||||
INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC ||
|
||||
be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
xfs_da_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf),
|
||||
(uint)(sizeof(leaf->hdr) - 1));
|
||||
}
|
||||
@ -1269,7 +1270,7 @@ xfs_dir2_leaf_log_tail(
|
||||
|
||||
mp = tp->t_mountp;
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAF1_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC);
|
||||
ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
|
||||
xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf),
|
||||
(uint)(mp->m_dirblksize - 1));
|
||||
@ -1314,7 +1315,7 @@ xfs_dir2_leaf_lookup(
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)dbp->data +
|
||||
XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT)));
|
||||
XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address)));
|
||||
/*
|
||||
* Return the found inode number.
|
||||
*/
|
||||
@ -1373,17 +1374,17 @@ xfs_dir2_leaf_lookup_int(
|
||||
* looking to match the name.
|
||||
*/
|
||||
for (lep = &leaf->ents[index], dbp = NULL, curdb = -1;
|
||||
index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval;
|
||||
index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval;
|
||||
lep++, index++) {
|
||||
/*
|
||||
* Skip over stale leaf entries.
|
||||
*/
|
||||
if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
|
||||
if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
|
||||
continue;
|
||||
/*
|
||||
* Get the new data block number.
|
||||
*/
|
||||
newdb = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
|
||||
newdb = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
|
||||
/*
|
||||
* If it's not the same as the old data block number,
|
||||
* need to pitch the old one and read the new one.
|
||||
@ -1406,7 +1407,7 @@ xfs_dir2_leaf_lookup_int(
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)dbp->data +
|
||||
XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)));
|
||||
XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address)));
|
||||
/*
|
||||
* If it matches then return it.
|
||||
*/
|
||||
@ -1435,7 +1436,7 @@ int /* error */
|
||||
xfs_dir2_leaf_removename(
|
||||
xfs_da_args_t *args) /* operation arguments */
|
||||
{
|
||||
xfs_dir2_data_off_t *bestsp; /* leaf block best freespace */
|
||||
__be16 *bestsp; /* leaf block best freespace */
|
||||
xfs_dir2_data_t *data; /* data block structure */
|
||||
xfs_dir2_db_t db; /* data block number */
|
||||
xfs_dabuf_t *dbp; /* data block buffer */
|
||||
@ -1471,14 +1472,14 @@ xfs_dir2_leaf_removename(
|
||||
* Point to the leaf entry, use that to point to the data entry.
|
||||
*/
|
||||
lep = &leaf->ents[index];
|
||||
db = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
|
||||
db = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)data + XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)));
|
||||
((char *)data + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address)));
|
||||
needscan = needlog = 0;
|
||||
oldbest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT);
|
||||
oldbest = be16_to_cpu(data->hdr.bestfree[0].length);
|
||||
ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
|
||||
bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
|
||||
ASSERT(INT_GET(bestsp[db], ARCH_CONVERT) == oldbest);
|
||||
ASSERT(be16_to_cpu(bestsp[db]) == oldbest);
|
||||
/*
|
||||
* Mark the former data entry unused.
|
||||
*/
|
||||
@ -1488,9 +1489,9 @@ xfs_dir2_leaf_removename(
|
||||
/*
|
||||
* We just mark the leaf entry stale by putting a null in it.
|
||||
*/
|
||||
INT_MOD(leaf->hdr.stale, ARCH_CONVERT, +1);
|
||||
be16_add(&leaf->hdr.stale, 1);
|
||||
xfs_dir2_leaf_log_header(tp, lbp);
|
||||
INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR);
|
||||
lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
|
||||
xfs_dir2_leaf_log_ents(tp, lbp, index, index);
|
||||
/*
|
||||
* Scan the freespace in the data block again if necessary,
|
||||
@ -1504,15 +1505,15 @@ xfs_dir2_leaf_removename(
|
||||
* If the longest freespace in the data block has changed,
|
||||
* put the new value in the bests table and log that.
|
||||
*/
|
||||
if (INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) != oldbest) {
|
||||
INT_COPY(bestsp[db], data->hdr.bestfree[0].length, ARCH_CONVERT);
|
||||
if (be16_to_cpu(data->hdr.bestfree[0].length) != oldbest) {
|
||||
bestsp[db] = data->hdr.bestfree[0].length;
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, db, db);
|
||||
}
|
||||
xfs_dir2_data_check(dp, dbp);
|
||||
/*
|
||||
* If the data block is now empty then get rid of the data block.
|
||||
*/
|
||||
if (INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) ==
|
||||
if (be16_to_cpu(data->hdr.bestfree[0].length) ==
|
||||
mp->m_dirblksize - (uint)sizeof(data->hdr)) {
|
||||
ASSERT(db != mp->m_dirdatablk);
|
||||
if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
|
||||
@ -1535,12 +1536,12 @@ xfs_dir2_leaf_removename(
|
||||
* If this is the last data block then compact the
|
||||
* bests table by getting rid of entries.
|
||||
*/
|
||||
if (db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1) {
|
||||
if (db == be32_to_cpu(ltp->bestcount) - 1) {
|
||||
/*
|
||||
* Look for the last active entry (i).
|
||||
*/
|
||||
for (i = db - 1; i > 0; i--) {
|
||||
if (INT_GET(bestsp[i], ARCH_CONVERT) != NULLDATAOFF)
|
||||
if (be16_to_cpu(bestsp[i]) != NULLDATAOFF)
|
||||
break;
|
||||
}
|
||||
/*
|
||||
@ -1548,12 +1549,12 @@ xfs_dir2_leaf_removename(
|
||||
* end are removed.
|
||||
*/
|
||||
memmove(&bestsp[db - i], bestsp,
|
||||
(INT_GET(ltp->bestcount, ARCH_CONVERT) - (db - i)) * sizeof(*bestsp));
|
||||
INT_MOD(ltp->bestcount, ARCH_CONVERT, -(db - i));
|
||||
(be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
|
||||
be32_add(<p->bestcount, -(db - i));
|
||||
xfs_dir2_leaf_log_tail(tp, lbp);
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
} else
|
||||
INT_SET(bestsp[db], ARCH_CONVERT, NULLDATAOFF);
|
||||
bestsp[db] = cpu_to_be16(NULLDATAOFF);
|
||||
}
|
||||
/*
|
||||
* If the data block was not the first one, drop it.
|
||||
@ -1604,7 +1605,7 @@ xfs_dir2_leaf_replace(
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)dbp->data +
|
||||
XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, INT_GET(lep->address, ARCH_CONVERT)));
|
||||
XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address)));
|
||||
ASSERT(args->inumber != INT_GET(dep->inumber, ARCH_CONVERT));
|
||||
/*
|
||||
* Put the new inode number in, log it.
|
||||
@ -1645,11 +1646,11 @@ xfs_dir2_leaf_search_hash(
|
||||
* Note, the table cannot be empty, so we have to go through the loop.
|
||||
* Binary search the leaf entries looking for our hash value.
|
||||
*/
|
||||
for (lep = leaf->ents, low = 0, high = INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1,
|
||||
for (lep = leaf->ents, low = 0, high = be16_to_cpu(leaf->hdr.count) - 1,
|
||||
hashwant = args->hashval;
|
||||
low <= high; ) {
|
||||
mid = (low + high) >> 1;
|
||||
if ((hash = INT_GET(lep[mid].hashval, ARCH_CONVERT)) == hashwant)
|
||||
if ((hash = be32_to_cpu(lep[mid].hashval)) == hashwant)
|
||||
break;
|
||||
if (hash < hashwant)
|
||||
low = mid + 1;
|
||||
@ -1660,7 +1661,7 @@ xfs_dir2_leaf_search_hash(
|
||||
* Found one, back up through all the equal hash values.
|
||||
*/
|
||||
if (hash == hashwant) {
|
||||
while (mid > 0 && INT_GET(lep[mid - 1].hashval, ARCH_CONVERT) == hashwant) {
|
||||
while (mid > 0 && be32_to_cpu(lep[mid - 1].hashval) == hashwant) {
|
||||
mid--;
|
||||
}
|
||||
}
|
||||
@ -1682,7 +1683,7 @@ xfs_dir2_leaf_trim_data(
|
||||
xfs_dabuf_t *lbp, /* leaf buffer */
|
||||
xfs_dir2_db_t db) /* data block number */
|
||||
{
|
||||
xfs_dir2_data_off_t *bestsp; /* leaf bests table */
|
||||
__be16 *bestsp; /* leaf bests table */
|
||||
#ifdef DEBUG
|
||||
xfs_dir2_data_t *data; /* data block structure */
|
||||
#endif
|
||||
@ -1706,7 +1707,7 @@ xfs_dir2_leaf_trim_data(
|
||||
}
|
||||
#ifdef DEBUG
|
||||
data = dbp->data;
|
||||
ASSERT(INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC);
|
||||
ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC);
|
||||
#endif
|
||||
/* this seems to be an error
|
||||
* data is only valid if DEBUG is defined?
|
||||
@ -1715,9 +1716,9 @@ xfs_dir2_leaf_trim_data(
|
||||
|
||||
leaf = lbp->data;
|
||||
ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
|
||||
ASSERT(INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) ==
|
||||
ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) ==
|
||||
mp->m_dirblksize - (uint)sizeof(data->hdr));
|
||||
ASSERT(db == INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
|
||||
ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
|
||||
/*
|
||||
* Get rid of the data block.
|
||||
*/
|
||||
@ -1730,10 +1731,10 @@ xfs_dir2_leaf_trim_data(
|
||||
* Eliminate the last bests entry from the table.
|
||||
*/
|
||||
bestsp = XFS_DIR2_LEAF_BESTS_P(ltp);
|
||||
INT_MOD(ltp->bestcount, ARCH_CONVERT, -1);
|
||||
memmove(&bestsp[1], &bestsp[0], INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(*bestsp));
|
||||
be32_add(<p->bestcount, -1);
|
||||
memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
|
||||
xfs_dir2_leaf_log_tail(tp, lbp);
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1805,7 +1806,7 @@ xfs_dir2_node_to_leaf(
|
||||
return 0;
|
||||
lbp = state->path.blk[0].bp;
|
||||
leaf = lbp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
/*
|
||||
* Read the freespace block.
|
||||
*/
|
||||
@ -1814,15 +1815,15 @@ xfs_dir2_node_to_leaf(
|
||||
return error;
|
||||
}
|
||||
free = fbp->data;
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(!free->hdr.firstdb);
|
||||
/*
|
||||
* Now see if the leafn and free data will fit in a leaf1.
|
||||
* If not, release the buffer and give up.
|
||||
*/
|
||||
if ((uint)sizeof(leaf->hdr) +
|
||||
(INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT)) * (uint)sizeof(leaf->ents[0]) +
|
||||
INT_GET(free->hdr.nvalid, ARCH_CONVERT) * (uint)sizeof(leaf->bests[0]) +
|
||||
(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) +
|
||||
be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) +
|
||||
(uint)sizeof(leaf->tail) >
|
||||
mp->m_dirblksize) {
|
||||
xfs_da_brelse(tp, fbp);
|
||||
@ -1832,22 +1833,22 @@ xfs_dir2_node_to_leaf(
|
||||
* If the leaf has any stale entries in it, compress them out.
|
||||
* The compact routine will log the header.
|
||||
*/
|
||||
if (INT_GET(leaf->hdr.stale, ARCH_CONVERT))
|
||||
if (be16_to_cpu(leaf->hdr.stale))
|
||||
xfs_dir2_leaf_compact(args, lbp);
|
||||
else
|
||||
xfs_dir2_leaf_log_header(tp, lbp);
|
||||
INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, XFS_DIR2_LEAF1_MAGIC);
|
||||
leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC);
|
||||
/*
|
||||
* Set up the leaf tail from the freespace block.
|
||||
*/
|
||||
ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf);
|
||||
INT_COPY(ltp->bestcount, free->hdr.nvalid, ARCH_CONVERT);
|
||||
ltp->bestcount = free->hdr.nvalid;
|
||||
/*
|
||||
* Set up the leaf bests table.
|
||||
*/
|
||||
memcpy(XFS_DIR2_LEAF_BESTS_P(ltp), free->bests,
|
||||
INT_GET(ltp->bestcount, ARCH_CONVERT) * sizeof(leaf->bests[0]));
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, 0, INT_GET(ltp->bestcount, ARCH_CONVERT) - 1);
|
||||
be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0]));
|
||||
xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
xfs_dir2_leaf_log_tail(tp, lbp);
|
||||
xfs_dir2_leaf_check(dp, lbp);
|
||||
/*
|
||||
|
@ -46,23 +46,23 @@ typedef __uint32_t xfs_dir2_dataptr_t;
|
||||
*/
|
||||
typedef struct xfs_dir2_leaf_hdr {
|
||||
xfs_da_blkinfo_t info; /* header for da routines */
|
||||
__uint16_t count; /* count of entries */
|
||||
__uint16_t stale; /* count of stale entries */
|
||||
__be16 count; /* count of entries */
|
||||
__be16 stale; /* count of stale entries */
|
||||
} xfs_dir2_leaf_hdr_t;
|
||||
|
||||
/*
|
||||
* Leaf block entry.
|
||||
*/
|
||||
typedef struct xfs_dir2_leaf_entry {
|
||||
xfs_dahash_t hashval; /* hash value of name */
|
||||
xfs_dir2_dataptr_t address; /* address of data entry */
|
||||
__be32 hashval; /* hash value of name */
|
||||
__be32 address; /* address of data entry */
|
||||
} xfs_dir2_leaf_entry_t;
|
||||
|
||||
/*
|
||||
* Leaf block tail.
|
||||
*/
|
||||
typedef struct xfs_dir2_leaf_tail {
|
||||
__uint32_t bestcount;
|
||||
__be32 bestcount;
|
||||
} xfs_dir2_leaf_tail_t;
|
||||
|
||||
/*
|
||||
@ -105,11 +105,10 @@ xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp)
|
||||
* Get address of the bests array in the single-leaf block.
|
||||
*/
|
||||
#define XFS_DIR2_LEAF_BESTS_P(ltp) xfs_dir2_leaf_bests_p(ltp)
|
||||
static inline xfs_dir2_data_off_t *
|
||||
static inline __be16 *
|
||||
xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp)
|
||||
{
|
||||
return (xfs_dir2_data_off_t *)
|
||||
(ltp) - INT_GET((ltp)->bestcount, ARCH_CONVERT);
|
||||
return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -76,7 +76,7 @@ xfs_dir2_free_log_bests(
|
||||
xfs_dir2_free_t *free; /* freespace structure */
|
||||
|
||||
free = bp->data;
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
|
||||
xfs_da_log_buf(tp, bp,
|
||||
(uint)((char *)&free->bests[first] - (char *)free),
|
||||
(uint)((char *)&free->bests[last] - (char *)free +
|
||||
@ -94,7 +94,7 @@ xfs_dir2_free_log_header(
|
||||
xfs_dir2_free_t *free; /* freespace structure */
|
||||
|
||||
free = bp->data;
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
|
||||
xfs_da_log_buf(tp, bp, (uint)((char *)&free->hdr - (char *)free),
|
||||
(uint)(sizeof(xfs_dir2_free_hdr_t) - 1));
|
||||
}
|
||||
@ -114,14 +114,14 @@ xfs_dir2_leaf_to_node(
|
||||
xfs_dabuf_t *fbp; /* freespace buffer */
|
||||
xfs_dir2_db_t fdb; /* freespace block number */
|
||||
xfs_dir2_free_t *free; /* freespace structure */
|
||||
xfs_dir2_data_off_t *from; /* pointer to freespace entry */
|
||||
__be16 *from; /* pointer to freespace entry */
|
||||
int i; /* leaf freespace index */
|
||||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int n; /* count of live freespc ents */
|
||||
xfs_dir2_data_off_t off; /* freespace entry value */
|
||||
xfs_dir2_data_off_t *to; /* pointer to freespace entry */
|
||||
__be16 *to; /* pointer to freespace entry */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
|
||||
xfs_dir2_trace_args_b("leaf_to_node", args, lbp);
|
||||
@ -149,28 +149,28 @@ xfs_dir2_leaf_to_node(
|
||||
/*
|
||||
* Initialize the freespace block header.
|
||||
*/
|
||||
INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC);
|
||||
free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC);
|
||||
free->hdr.firstdb = 0;
|
||||
ASSERT(INT_GET(ltp->bestcount, ARCH_CONVERT) <= (uint)dp->i_d.di_size / mp->m_dirblksize);
|
||||
INT_COPY(free->hdr.nvalid, ltp->bestcount, ARCH_CONVERT);
|
||||
ASSERT(be32_to_cpu(ltp->bestcount) <= (uint)dp->i_d.di_size / mp->m_dirblksize);
|
||||
free->hdr.nvalid = ltp->bestcount;
|
||||
/*
|
||||
* Copy freespace entries from the leaf block to the new block.
|
||||
* Count active entries.
|
||||
*/
|
||||
for (i = n = 0, from = XFS_DIR2_LEAF_BESTS_P(ltp), to = free->bests;
|
||||
i < INT_GET(ltp->bestcount, ARCH_CONVERT); i++, from++, to++) {
|
||||
if ((off = INT_GET(*from, ARCH_CONVERT)) != NULLDATAOFF)
|
||||
i < be32_to_cpu(ltp->bestcount); i++, from++, to++) {
|
||||
if ((off = be16_to_cpu(*from)) != NULLDATAOFF)
|
||||
n++;
|
||||
INT_SET(*to, ARCH_CONVERT, off);
|
||||
*to = cpu_to_be16(off);
|
||||
}
|
||||
INT_SET(free->hdr.nused, ARCH_CONVERT, n);
|
||||
INT_SET(leaf->hdr.info.magic, ARCH_CONVERT, XFS_DIR2_LEAFN_MAGIC);
|
||||
free->hdr.nused = cpu_to_be32(n);
|
||||
leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC);
|
||||
/*
|
||||
* Log everything.
|
||||
*/
|
||||
xfs_dir2_leaf_log_header(tp, lbp);
|
||||
xfs_dir2_free_log_header(tp, fbp);
|
||||
xfs_dir2_free_log_bests(tp, fbp, 0, INT_GET(free->hdr.nvalid, ARCH_CONVERT) - 1);
|
||||
xfs_dir2_free_log_bests(tp, fbp, 0, be32_to_cpu(free->hdr.nvalid) - 1);
|
||||
xfs_da_buf_done(fbp);
|
||||
xfs_dir2_leafn_check(dp, lbp);
|
||||
return 0;
|
||||
@ -217,15 +217,15 @@ xfs_dir2_leafn_add(
|
||||
* a compact.
|
||||
*/
|
||||
|
||||
if (INT_GET(leaf->hdr.count, ARCH_CONVERT) == XFS_DIR2_MAX_LEAF_ENTS(mp)) {
|
||||
if (be16_to_cpu(leaf->hdr.count) == XFS_DIR2_MAX_LEAF_ENTS(mp)) {
|
||||
if (!leaf->hdr.stale)
|
||||
return XFS_ERROR(ENOSPC);
|
||||
compact = INT_GET(leaf->hdr.stale, ARCH_CONVERT) > 1;
|
||||
compact = be16_to_cpu(leaf->hdr.stale) > 1;
|
||||
} else
|
||||
compact = 0;
|
||||
ASSERT(index == 0 || INT_GET(leaf->ents[index - 1].hashval, ARCH_CONVERT) <= args->hashval);
|
||||
ASSERT(index == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
|
||||
INT_GET(leaf->ents[index].hashval, ARCH_CONVERT) >= args->hashval);
|
||||
ASSERT(index == 0 || be32_to_cpu(leaf->ents[index - 1].hashval) <= args->hashval);
|
||||
ASSERT(index == be16_to_cpu(leaf->hdr.count) ||
|
||||
be32_to_cpu(leaf->ents[index].hashval) >= args->hashval);
|
||||
|
||||
if (args->justcheck)
|
||||
return 0;
|
||||
@ -242,7 +242,7 @@ xfs_dir2_leafn_add(
|
||||
* Set impossible logging indices for this case.
|
||||
*/
|
||||
else if (leaf->hdr.stale) {
|
||||
lfloglow = INT_GET(leaf->hdr.count, ARCH_CONVERT);
|
||||
lfloglow = be16_to_cpu(leaf->hdr.count);
|
||||
lfloghigh = -1;
|
||||
}
|
||||
/*
|
||||
@ -250,12 +250,12 @@ xfs_dir2_leafn_add(
|
||||
*/
|
||||
if (!leaf->hdr.stale) {
|
||||
lep = &leaf->ents[index];
|
||||
if (index < INT_GET(leaf->hdr.count, ARCH_CONVERT))
|
||||
if (index < be16_to_cpu(leaf->hdr.count))
|
||||
memmove(lep + 1, lep,
|
||||
(INT_GET(leaf->hdr.count, ARCH_CONVERT) - index) * sizeof(*lep));
|
||||
(be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep));
|
||||
lfloglow = index;
|
||||
lfloghigh = INT_GET(leaf->hdr.count, ARCH_CONVERT);
|
||||
INT_MOD(leaf->hdr.count, ARCH_CONVERT, +1);
|
||||
lfloghigh = be16_to_cpu(leaf->hdr.count);
|
||||
be16_add(&leaf->hdr.count, 1);
|
||||
}
|
||||
/*
|
||||
* There are stale entries. We'll use one for the new entry.
|
||||
@ -271,7 +271,7 @@ xfs_dir2_leafn_add(
|
||||
*/
|
||||
for (lowstale = index - 1;
|
||||
lowstale >= 0 &&
|
||||
INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) !=
|
||||
be32_to_cpu(leaf->ents[lowstale].address) !=
|
||||
XFS_DIR2_NULL_DATAPTR;
|
||||
lowstale--)
|
||||
continue;
|
||||
@ -281,8 +281,8 @@ xfs_dir2_leafn_add(
|
||||
* lowstale already found.
|
||||
*/
|
||||
for (highstale = index;
|
||||
highstale < INT_GET(leaf->hdr.count, ARCH_CONVERT) &&
|
||||
INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) !=
|
||||
highstale < be16_to_cpu(leaf->hdr.count) &&
|
||||
be32_to_cpu(leaf->ents[highstale].address) !=
|
||||
XFS_DIR2_NULL_DATAPTR &&
|
||||
(lowstale < 0 ||
|
||||
index - lowstale - 1 >= highstale - index);
|
||||
@ -294,9 +294,9 @@ xfs_dir2_leafn_add(
|
||||
* Shift entries up toward the stale slot.
|
||||
*/
|
||||
if (lowstale >= 0 &&
|
||||
(highstale == INT_GET(leaf->hdr.count, ARCH_CONVERT) ||
|
||||
(highstale == be16_to_cpu(leaf->hdr.count) ||
|
||||
index - lowstale - 1 < highstale - index)) {
|
||||
ASSERT(INT_GET(leaf->ents[lowstale].address, ARCH_CONVERT) ==
|
||||
ASSERT(be32_to_cpu(leaf->ents[lowstale].address) ==
|
||||
XFS_DIR2_NULL_DATAPTR);
|
||||
ASSERT(index - lowstale - 1 >= 0);
|
||||
if (index - lowstale - 1 > 0)
|
||||
@ -312,7 +312,7 @@ xfs_dir2_leafn_add(
|
||||
* Shift entries down toward the stale slot.
|
||||
*/
|
||||
else {
|
||||
ASSERT(INT_GET(leaf->ents[highstale].address, ARCH_CONVERT) ==
|
||||
ASSERT(be32_to_cpu(leaf->ents[highstale].address) ==
|
||||
XFS_DIR2_NULL_DATAPTR);
|
||||
ASSERT(highstale - index >= 0);
|
||||
if (highstale - index > 0)
|
||||
@ -323,13 +323,14 @@ xfs_dir2_leafn_add(
|
||||
lfloglow = MIN(index, lfloglow);
|
||||
lfloghigh = MAX(highstale, lfloghigh);
|
||||
}
|
||||
INT_MOD(leaf->hdr.stale, ARCH_CONVERT, -1);
|
||||
be16_add(&leaf->hdr.stale, -1);
|
||||
}
|
||||
/*
|
||||
* Insert the new entry, log everything.
|
||||
*/
|
||||
INT_SET(lep->hashval, ARCH_CONVERT, args->hashval);
|
||||
INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_DB_OFF_TO_DATAPTR(mp, args->blkno, args->index));
|
||||
lep->hashval = cpu_to_be32(args->hashval);
|
||||
lep->address = cpu_to_be32(XFS_DIR2_DB_OFF_TO_DATAPTR(mp,
|
||||
args->blkno, args->index));
|
||||
xfs_dir2_leaf_log_header(tp, bp);
|
||||
xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh);
|
||||
xfs_dir2_leafn_check(dp, bp);
|
||||
@ -352,17 +353,17 @@ xfs_dir2_leafn_check(
|
||||
|
||||
leaf = bp->data;
|
||||
mp = dp->i_mount;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) <= XFS_DIR2_MAX_LEAF_ENTS(mp));
|
||||
for (i = stale = 0; i < INT_GET(leaf->hdr.count, ARCH_CONVERT); i++) {
|
||||
if (i + 1 < INT_GET(leaf->hdr.count, ARCH_CONVERT)) {
|
||||
ASSERT(INT_GET(leaf->ents[i].hashval, ARCH_CONVERT) <=
|
||||
INT_GET(leaf->ents[i + 1].hashval, ARCH_CONVERT));
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.count) <= XFS_DIR2_MAX_LEAF_ENTS(mp));
|
||||
for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) {
|
||||
if (i + 1 < be16_to_cpu(leaf->hdr.count)) {
|
||||
ASSERT(be32_to_cpu(leaf->ents[i].hashval) <=
|
||||
be32_to_cpu(leaf->ents[i + 1].hashval));
|
||||
}
|
||||
if (INT_GET(leaf->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
|
||||
if (be32_to_cpu(leaf->ents[i].address) == XFS_DIR2_NULL_DATAPTR)
|
||||
stale++;
|
||||
}
|
||||
ASSERT(INT_GET(leaf->hdr.stale, ARCH_CONVERT) == stale);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.stale) == stale);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
@ -378,12 +379,12 @@ xfs_dir2_leafn_lasthash(
|
||||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
if (count)
|
||||
*count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
|
||||
*count = be16_to_cpu(leaf->hdr.count);
|
||||
if (!leaf->hdr.count)
|
||||
return 0;
|
||||
return INT_GET(leaf->ents[INT_GET(leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
|
||||
return be32_to_cpu(leaf->ents[be16_to_cpu(leaf->hdr.count) - 1].hashval);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -419,9 +420,9 @@ xfs_dir2_leafn_lookup_int(
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
#ifdef __KERNEL__
|
||||
ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) > 0);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.count) > 0);
|
||||
#endif
|
||||
xfs_dir2_leafn_check(dp, bp);
|
||||
/*
|
||||
@ -443,7 +444,7 @@ xfs_dir2_leafn_lookup_int(
|
||||
curdb = -1;
|
||||
length = XFS_DIR2_DATA_ENTSIZE(args->namelen);
|
||||
if ((free = (curbp ? curbp->data : NULL)))
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
|
||||
}
|
||||
/*
|
||||
* For others, it's a data block buffer, get the block number.
|
||||
@ -456,17 +457,17 @@ xfs_dir2_leafn_lookup_int(
|
||||
* Loop over leaf entries with the right hash value.
|
||||
*/
|
||||
for (lep = &leaf->ents[index];
|
||||
index < INT_GET(leaf->hdr.count, ARCH_CONVERT) && INT_GET(lep->hashval, ARCH_CONVERT) == args->hashval;
|
||||
index < be16_to_cpu(leaf->hdr.count) && be32_to_cpu(lep->hashval) == args->hashval;
|
||||
lep++, index++) {
|
||||
/*
|
||||
* Skip stale leaf entries.
|
||||
*/
|
||||
if (INT_GET(lep->address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
|
||||
if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
|
||||
continue;
|
||||
/*
|
||||
* Pull the data block number from the entry.
|
||||
*/
|
||||
newdb = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
|
||||
newdb = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
|
||||
/*
|
||||
* For addname, we're looking for a place to put the new entry.
|
||||
* We want to use a data block with an entry of equal
|
||||
@ -506,15 +507,15 @@ xfs_dir2_leafn_lookup_int(
|
||||
}
|
||||
curfdb = newfdb;
|
||||
free = curbp->data;
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) ==
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) ==
|
||||
XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT((INT_GET(free->hdr.firstdb, ARCH_CONVERT) %
|
||||
ASSERT((be32_to_cpu(free->hdr.firstdb) %
|
||||
XFS_DIR2_MAX_FREE_BESTS(mp)) ==
|
||||
0);
|
||||
ASSERT(INT_GET(free->hdr.firstdb, ARCH_CONVERT) <= curdb);
|
||||
ASSERT(be32_to_cpu(free->hdr.firstdb) <= curdb);
|
||||
ASSERT(curdb <
|
||||
INT_GET(free->hdr.firstdb, ARCH_CONVERT) +
|
||||
INT_GET(free->hdr.nvalid, ARCH_CONVERT));
|
||||
be32_to_cpu(free->hdr.firstdb) +
|
||||
be32_to_cpu(free->hdr.nvalid));
|
||||
}
|
||||
/*
|
||||
* Get the index for our entry.
|
||||
@ -523,12 +524,12 @@ xfs_dir2_leafn_lookup_int(
|
||||
/*
|
||||
* If it has room, return it.
|
||||
*/
|
||||
if (unlikely(INT_GET(free->bests[fi], ARCH_CONVERT) == NULLDATAOFF)) {
|
||||
if (unlikely(be16_to_cpu(free->bests[fi]) == NULLDATAOFF)) {
|
||||
XFS_ERROR_REPORT("xfs_dir2_leafn_lookup_int",
|
||||
XFS_ERRLEVEL_LOW, mp);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
if (INT_GET(free->bests[fi], ARCH_CONVERT) >= length) {
|
||||
if (be16_to_cpu(free->bests[fi]) >= length) {
|
||||
*indexp = index;
|
||||
state->extravalid = 1;
|
||||
state->extrablk.bp = curbp;
|
||||
@ -572,7 +573,7 @@ xfs_dir2_leafn_lookup_int(
|
||||
*/
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)curbp->data +
|
||||
XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT)));
|
||||
XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address)));
|
||||
/*
|
||||
* Compare the entry, return it if it matches.
|
||||
*/
|
||||
@ -619,7 +620,7 @@ xfs_dir2_leafn_lookup_int(
|
||||
* Return the final index, that will be the insertion point.
|
||||
*/
|
||||
*indexp = index;
|
||||
ASSERT(index == INT_GET(leaf->hdr.count, ARCH_CONVERT) || args->oknoent);
|
||||
ASSERT(index == be16_to_cpu(leaf->hdr.count) || args->oknoent);
|
||||
return XFS_ERROR(ENOENT);
|
||||
}
|
||||
|
||||
@ -657,12 +658,12 @@ xfs_dir2_leafn_moveents(
|
||||
* destination leaf entries, open up a hole in the destination
|
||||
* to hold the new entries.
|
||||
*/
|
||||
if (start_d < INT_GET(leaf_d->hdr.count, ARCH_CONVERT)) {
|
||||
if (start_d < be16_to_cpu(leaf_d->hdr.count)) {
|
||||
memmove(&leaf_d->ents[start_d + count], &leaf_d->ents[start_d],
|
||||
(INT_GET(leaf_d->hdr.count, ARCH_CONVERT) - start_d) *
|
||||
(be16_to_cpu(leaf_d->hdr.count) - start_d) *
|
||||
sizeof(xfs_dir2_leaf_entry_t));
|
||||
xfs_dir2_leaf_log_ents(tp, bp_d, start_d + count,
|
||||
count + INT_GET(leaf_d->hdr.count, ARCH_CONVERT) - 1);
|
||||
count + be16_to_cpu(leaf_d->hdr.count) - 1);
|
||||
}
|
||||
/*
|
||||
* If the source has stale leaves, count the ones in the copy range
|
||||
@ -672,7 +673,7 @@ xfs_dir2_leafn_moveents(
|
||||
int i; /* temp leaf index */
|
||||
|
||||
for (i = start_s, stale = 0; i < start_s + count; i++) {
|
||||
if (INT_GET(leaf_s->ents[i].address, ARCH_CONVERT) == XFS_DIR2_NULL_DATAPTR)
|
||||
if (be32_to_cpu(leaf_s->ents[i].address) == XFS_DIR2_NULL_DATAPTR)
|
||||
stale++;
|
||||
}
|
||||
} else
|
||||
@ -687,7 +688,7 @@ xfs_dir2_leafn_moveents(
|
||||
* If there are source entries after the ones we copied,
|
||||
* delete the ones we copied by sliding the next ones down.
|
||||
*/
|
||||
if (start_s + count < INT_GET(leaf_s->hdr.count, ARCH_CONVERT)) {
|
||||
if (start_s + count < be16_to_cpu(leaf_s->hdr.count)) {
|
||||
memmove(&leaf_s->ents[start_s], &leaf_s->ents[start_s + count],
|
||||
count * sizeof(xfs_dir2_leaf_entry_t));
|
||||
xfs_dir2_leaf_log_ents(tp, bp_s, start_s, start_s + count - 1);
|
||||
@ -695,10 +696,10 @@ xfs_dir2_leafn_moveents(
|
||||
/*
|
||||
* Update the headers and log them.
|
||||
*/
|
||||
INT_MOD(leaf_s->hdr.count, ARCH_CONVERT, -(count));
|
||||
INT_MOD(leaf_s->hdr.stale, ARCH_CONVERT, -(stale));
|
||||
INT_MOD(leaf_d->hdr.count, ARCH_CONVERT, count);
|
||||
INT_MOD(leaf_d->hdr.stale, ARCH_CONVERT, stale);
|
||||
be16_add(&leaf_s->hdr.count, -(count));
|
||||
be16_add(&leaf_s->hdr.stale, -(stale));
|
||||
be16_add(&leaf_d->hdr.count, count);
|
||||
be16_add(&leaf_d->hdr.stale, stale);
|
||||
xfs_dir2_leaf_log_header(tp, bp_s);
|
||||
xfs_dir2_leaf_log_header(tp, bp_d);
|
||||
xfs_dir2_leafn_check(args->dp, bp_s);
|
||||
@ -719,13 +720,13 @@ xfs_dir2_leafn_order(
|
||||
|
||||
leaf1 = leaf1_bp->data;
|
||||
leaf2 = leaf2_bp->data;
|
||||
ASSERT(INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0 &&
|
||||
INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0 &&
|
||||
(INT_GET(leaf2->ents[0].hashval, ARCH_CONVERT) < INT_GET(leaf1->ents[0].hashval, ARCH_CONVERT) ||
|
||||
INT_GET(leaf2->ents[INT_GET(leaf2->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT) <
|
||||
INT_GET(leaf1->ents[INT_GET(leaf1->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT)))
|
||||
ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
if (be16_to_cpu(leaf1->hdr.count) > 0 &&
|
||||
be16_to_cpu(leaf2->hdr.count) > 0 &&
|
||||
(be32_to_cpu(leaf2->ents[0].hashval) < be32_to_cpu(leaf1->ents[0].hashval) ||
|
||||
be32_to_cpu(leaf2->ents[be16_to_cpu(leaf2->hdr.count) - 1].hashval) <
|
||||
be32_to_cpu(leaf1->ents[be16_to_cpu(leaf1->hdr.count) - 1].hashval)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@ -768,9 +769,9 @@ xfs_dir2_leafn_rebalance(
|
||||
}
|
||||
leaf1 = blk1->bp->data;
|
||||
leaf2 = blk2->bp->data;
|
||||
oldsum = INT_GET(leaf1->hdr.count, ARCH_CONVERT) + INT_GET(leaf2->hdr.count, ARCH_CONVERT);
|
||||
oldsum = be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count);
|
||||
#ifdef DEBUG
|
||||
oldstale = INT_GET(leaf1->hdr.stale, ARCH_CONVERT) + INT_GET(leaf2->hdr.stale, ARCH_CONVERT);
|
||||
oldstale = be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale);
|
||||
#endif
|
||||
mid = oldsum >> 1;
|
||||
/*
|
||||
@ -780,10 +781,10 @@ xfs_dir2_leafn_rebalance(
|
||||
if (oldsum & 1) {
|
||||
xfs_dahash_t midhash; /* middle entry hash value */
|
||||
|
||||
if (mid >= INT_GET(leaf1->hdr.count, ARCH_CONVERT))
|
||||
midhash = INT_GET(leaf2->ents[mid - INT_GET(leaf1->hdr.count, ARCH_CONVERT)].hashval, ARCH_CONVERT);
|
||||
if (mid >= be16_to_cpu(leaf1->hdr.count))
|
||||
midhash = be32_to_cpu(leaf2->ents[mid - be16_to_cpu(leaf1->hdr.count)].hashval);
|
||||
else
|
||||
midhash = INT_GET(leaf1->ents[mid].hashval, ARCH_CONVERT);
|
||||
midhash = be32_to_cpu(leaf1->ents[mid].hashval);
|
||||
isleft = args->hashval <= midhash;
|
||||
}
|
||||
/*
|
||||
@ -797,30 +798,30 @@ xfs_dir2_leafn_rebalance(
|
||||
* Calculate moved entry count. Positive means left-to-right,
|
||||
* negative means right-to-left. Then move the entries.
|
||||
*/
|
||||
count = INT_GET(leaf1->hdr.count, ARCH_CONVERT) - mid + (isleft == 0);
|
||||
count = be16_to_cpu(leaf1->hdr.count) - mid + (isleft == 0);
|
||||
if (count > 0)
|
||||
xfs_dir2_leafn_moveents(args, blk1->bp,
|
||||
INT_GET(leaf1->hdr.count, ARCH_CONVERT) - count, blk2->bp, 0, count);
|
||||
be16_to_cpu(leaf1->hdr.count) - count, blk2->bp, 0, count);
|
||||
else if (count < 0)
|
||||
xfs_dir2_leafn_moveents(args, blk2->bp, 0, blk1->bp,
|
||||
INT_GET(leaf1->hdr.count, ARCH_CONVERT), count);
|
||||
ASSERT(INT_GET(leaf1->hdr.count, ARCH_CONVERT) + INT_GET(leaf2->hdr.count, ARCH_CONVERT) == oldsum);
|
||||
ASSERT(INT_GET(leaf1->hdr.stale, ARCH_CONVERT) + INT_GET(leaf2->hdr.stale, ARCH_CONVERT) == oldstale);
|
||||
be16_to_cpu(leaf1->hdr.count), count);
|
||||
ASSERT(be16_to_cpu(leaf1->hdr.count) + be16_to_cpu(leaf2->hdr.count) == oldsum);
|
||||
ASSERT(be16_to_cpu(leaf1->hdr.stale) + be16_to_cpu(leaf2->hdr.stale) == oldstale);
|
||||
/*
|
||||
* Mark whether we're inserting into the old or new leaf.
|
||||
*/
|
||||
if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) < INT_GET(leaf2->hdr.count, ARCH_CONVERT))
|
||||
if (be16_to_cpu(leaf1->hdr.count) < be16_to_cpu(leaf2->hdr.count))
|
||||
state->inleaf = swap;
|
||||
else if (INT_GET(leaf1->hdr.count, ARCH_CONVERT) > INT_GET(leaf2->hdr.count, ARCH_CONVERT))
|
||||
else if (be16_to_cpu(leaf1->hdr.count) > be16_to_cpu(leaf2->hdr.count))
|
||||
state->inleaf = !swap;
|
||||
else
|
||||
state->inleaf =
|
||||
swap ^ (blk1->index <= INT_GET(leaf1->hdr.count, ARCH_CONVERT));
|
||||
swap ^ (blk1->index <= be16_to_cpu(leaf1->hdr.count));
|
||||
/*
|
||||
* Adjust the expected index for insertion.
|
||||
*/
|
||||
if (!state->inleaf)
|
||||
blk2->index = blk1->index - INT_GET(leaf1->hdr.count, ARCH_CONVERT);
|
||||
blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count);
|
||||
|
||||
/*
|
||||
* Finally sanity check just to make sure we are not returning a negative index
|
||||
@ -867,7 +868,7 @@ xfs_dir2_leafn_remove(
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
/*
|
||||
* Point to the entry we're removing.
|
||||
*/
|
||||
@ -875,17 +876,17 @@ xfs_dir2_leafn_remove(
|
||||
/*
|
||||
* Extract the data block and offset from the entry.
|
||||
*/
|
||||
db = XFS_DIR2_DATAPTR_TO_DB(mp, INT_GET(lep->address, ARCH_CONVERT));
|
||||
db = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address));
|
||||
ASSERT(dblk->blkno == db);
|
||||
off = XFS_DIR2_DATAPTR_TO_OFF(mp, INT_GET(lep->address, ARCH_CONVERT));
|
||||
off = XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address));
|
||||
ASSERT(dblk->index == off);
|
||||
/*
|
||||
* Kill the leaf entry by marking it stale.
|
||||
* Log the leaf block changes.
|
||||
*/
|
||||
INT_MOD(leaf->hdr.stale, ARCH_CONVERT, +1);
|
||||
be16_add(&leaf->hdr.stale, 1);
|
||||
xfs_dir2_leaf_log_header(tp, bp);
|
||||
INT_SET(lep->address, ARCH_CONVERT, XFS_DIR2_NULL_DATAPTR);
|
||||
lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
|
||||
xfs_dir2_leaf_log_ents(tp, bp, index, index);
|
||||
/*
|
||||
* Make the data entry free. Keep track of the longest freespace
|
||||
@ -894,7 +895,7 @@ xfs_dir2_leafn_remove(
|
||||
dbp = dblk->bp;
|
||||
data = dbp->data;
|
||||
dep = (xfs_dir2_data_entry_t *)((char *)data + off);
|
||||
longest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT);
|
||||
longest = be16_to_cpu(data->hdr.bestfree[0].length);
|
||||
needlog = needscan = 0;
|
||||
xfs_dir2_data_make_free(tp, dbp, off,
|
||||
XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan);
|
||||
@ -911,7 +912,7 @@ xfs_dir2_leafn_remove(
|
||||
* If the longest data block freespace changes, need to update
|
||||
* the corresponding freeblock entry.
|
||||
*/
|
||||
if (longest < INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) {
|
||||
if (longest < be16_to_cpu(data->hdr.bestfree[0].length)) {
|
||||
int error; /* error return value */
|
||||
xfs_dabuf_t *fbp; /* freeblock buffer */
|
||||
xfs_dir2_db_t fdb; /* freeblock block number */
|
||||
@ -929,15 +930,15 @@ xfs_dir2_leafn_remove(
|
||||
return error;
|
||||
}
|
||||
free = fbp->data;
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(INT_GET(free->hdr.firstdb, ARCH_CONVERT) ==
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(be32_to_cpu(free->hdr.firstdb) ==
|
||||
XFS_DIR2_MAX_FREE_BESTS(mp) *
|
||||
(fdb - XFS_DIR2_FREE_FIRSTDB(mp)));
|
||||
/*
|
||||
* Calculate which entry we need to fix.
|
||||
*/
|
||||
findex = XFS_DIR2_DB_TO_FDINDEX(mp, db);
|
||||
longest = INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT);
|
||||
longest = be16_to_cpu(data->hdr.bestfree[0].length);
|
||||
/*
|
||||
* If the data block is now empty we can get rid of it
|
||||
* (usually).
|
||||
@ -969,7 +970,7 @@ xfs_dir2_leafn_remove(
|
||||
/*
|
||||
* One less used entry in the free table.
|
||||
*/
|
||||
INT_MOD(free->hdr.nused, ARCH_CONVERT, -1);
|
||||
free->hdr.nused = cpu_to_be32(-1);
|
||||
xfs_dir2_free_log_header(tp, fbp);
|
||||
/*
|
||||
* If this was the last entry in the table, we can
|
||||
@ -977,21 +978,21 @@ xfs_dir2_leafn_remove(
|
||||
* entries at the end referring to non-existent
|
||||
* data blocks, get those too.
|
||||
*/
|
||||
if (findex == INT_GET(free->hdr.nvalid, ARCH_CONVERT) - 1) {
|
||||
if (findex == be32_to_cpu(free->hdr.nvalid) - 1) {
|
||||
int i; /* free entry index */
|
||||
|
||||
for (i = findex - 1;
|
||||
i >= 0 && INT_GET(free->bests[i], ARCH_CONVERT) == NULLDATAOFF;
|
||||
i >= 0 && be16_to_cpu(free->bests[i]) == NULLDATAOFF;
|
||||
i--)
|
||||
continue;
|
||||
INT_SET(free->hdr.nvalid, ARCH_CONVERT, i + 1);
|
||||
free->hdr.nvalid = cpu_to_be32(i + 1);
|
||||
logfree = 0;
|
||||
}
|
||||
/*
|
||||
* Not the last entry, just punch it out.
|
||||
*/
|
||||
else {
|
||||
INT_SET(free->bests[findex], ARCH_CONVERT, NULLDATAOFF);
|
||||
free->bests[findex] = cpu_to_be16(NULLDATAOFF);
|
||||
logfree = 1;
|
||||
}
|
||||
/*
|
||||
@ -1017,7 +1018,7 @@ xfs_dir2_leafn_remove(
|
||||
* the new value.
|
||||
*/
|
||||
else {
|
||||
INT_SET(free->bests[findex], ARCH_CONVERT, longest);
|
||||
free->bests[findex] = cpu_to_be16(longest);
|
||||
logfree = 1;
|
||||
}
|
||||
/*
|
||||
@ -1039,7 +1040,7 @@ xfs_dir2_leafn_remove(
|
||||
*rval =
|
||||
((uint)sizeof(leaf->hdr) +
|
||||
(uint)sizeof(leaf->ents[0]) *
|
||||
(INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT))) <
|
||||
(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale))) <
|
||||
mp->m_dir_magicpct;
|
||||
return 0;
|
||||
}
|
||||
@ -1138,9 +1139,9 @@ xfs_dir2_leafn_toosmall(
|
||||
*/
|
||||
blk = &state->path.blk[state->path.active - 1];
|
||||
info = blk->bp->data;
|
||||
ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
leaf = (xfs_dir2_leaf_t *)info;
|
||||
count = INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT);
|
||||
count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
|
||||
bytes = (uint)sizeof(leaf->hdr) + count * (uint)sizeof(leaf->ents[0]);
|
||||
if (bytes > (state->blocksize >> 1)) {
|
||||
/*
|
||||
@ -1160,7 +1161,7 @@ xfs_dir2_leafn_toosmall(
|
||||
* Make altpath point to the block we want to keep and
|
||||
* path point to the block we want to drop (this one).
|
||||
*/
|
||||
forward = info->forw;
|
||||
forward = (info->forw != 0);
|
||||
memcpy(&state->altpath, &state->path, sizeof(state->path));
|
||||
error = xfs_da_path_shift(state, &state->altpath, forward, 0,
|
||||
&rval);
|
||||
@ -1176,9 +1177,9 @@ xfs_dir2_leafn_toosmall(
|
||||
* We prefer coalescing with the lower numbered sibling so as
|
||||
* to shrink a directory over time.
|
||||
*/
|
||||
forward = INT_GET(info->forw, ARCH_CONVERT) < INT_GET(info->back, ARCH_CONVERT);
|
||||
forward = be32_to_cpu(info->forw) < be32_to_cpu(info->back);
|
||||
for (i = 0, bp = NULL; i < 2; forward = !forward, i++) {
|
||||
blkno = forward ?INT_GET( info->forw, ARCH_CONVERT) : INT_GET(info->back, ARCH_CONVERT);
|
||||
blkno = forward ? be32_to_cpu(info->forw) : be32_to_cpu(info->back);
|
||||
if (blkno == 0)
|
||||
continue;
|
||||
/*
|
||||
@ -1194,11 +1195,11 @@ xfs_dir2_leafn_toosmall(
|
||||
* Count bytes in the two blocks combined.
|
||||
*/
|
||||
leaf = (xfs_dir2_leaf_t *)info;
|
||||
count = INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT);
|
||||
count = be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
|
||||
bytes = state->blocksize - (state->blocksize >> 2);
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
count += INT_GET(leaf->hdr.count, ARCH_CONVERT) - INT_GET(leaf->hdr.stale, ARCH_CONVERT);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
count += be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale);
|
||||
bytes -= count * (uint)sizeof(leaf->ents[0]);
|
||||
/*
|
||||
* Fits with at least 25% to spare.
|
||||
@ -1256,27 +1257,27 @@ xfs_dir2_leafn_unbalance(
|
||||
ASSERT(save_blk->magic == XFS_DIR2_LEAFN_MAGIC);
|
||||
drop_leaf = drop_blk->bp->data;
|
||||
save_leaf = save_blk->bp->data;
|
||||
ASSERT(INT_GET(drop_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(INT_GET(save_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC);
|
||||
/*
|
||||
* If there are any stale leaf entries, take this opportunity
|
||||
* to purge them.
|
||||
*/
|
||||
if (INT_GET(drop_leaf->hdr.stale, ARCH_CONVERT))
|
||||
if (drop_leaf->hdr.stale)
|
||||
xfs_dir2_leaf_compact(args, drop_blk->bp);
|
||||
if (INT_GET(save_leaf->hdr.stale, ARCH_CONVERT))
|
||||
if (save_leaf->hdr.stale)
|
||||
xfs_dir2_leaf_compact(args, save_blk->bp);
|
||||
/*
|
||||
* Move the entries from drop to the appropriate end of save.
|
||||
*/
|
||||
drop_blk->hashval = INT_GET(drop_leaf->ents[INT_GET(drop_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
|
||||
drop_blk->hashval = be32_to_cpu(drop_leaf->ents[be16_to_cpu(drop_leaf->hdr.count) - 1].hashval);
|
||||
if (xfs_dir2_leafn_order(save_blk->bp, drop_blk->bp))
|
||||
xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp, 0,
|
||||
INT_GET(drop_leaf->hdr.count, ARCH_CONVERT));
|
||||
be16_to_cpu(drop_leaf->hdr.count));
|
||||
else
|
||||
xfs_dir2_leafn_moveents(args, drop_blk->bp, 0, save_blk->bp,
|
||||
INT_GET(save_leaf->hdr.count, ARCH_CONVERT), INT_GET(drop_leaf->hdr.count, ARCH_CONVERT));
|
||||
save_blk->hashval = INT_GET(save_leaf->ents[INT_GET(save_leaf->hdr.count, ARCH_CONVERT) - 1].hashval, ARCH_CONVERT);
|
||||
be16_to_cpu(save_leaf->hdr.count), be16_to_cpu(drop_leaf->hdr.count));
|
||||
save_blk->hashval = be32_to_cpu(save_leaf->ents[be16_to_cpu(save_leaf->hdr.count) - 1].hashval);
|
||||
xfs_dir2_leafn_check(args->dp, save_blk->bp);
|
||||
}
|
||||
|
||||
@ -1378,7 +1379,7 @@ xfs_dir2_node_addname_int(
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int needlog; /* need to log data header */
|
||||
int needscan; /* need to rescan data frees */
|
||||
xfs_dir2_data_off_t *tagp; /* data entry tag pointer */
|
||||
__be16 *tagp; /* data entry tag pointer */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
|
||||
dp = args->dp;
|
||||
@ -1397,7 +1398,7 @@ xfs_dir2_node_addname_int(
|
||||
*/
|
||||
ifbno = fblk->blkno;
|
||||
free = fbp->data;
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
|
||||
findex = fblk->index;
|
||||
/*
|
||||
* This means the free entry showed that the data block had
|
||||
@ -1405,10 +1406,10 @@ xfs_dir2_node_addname_int(
|
||||
* Use that data block.
|
||||
*/
|
||||
if (findex >= 0) {
|
||||
ASSERT(findex < INT_GET(free->hdr.nvalid, ARCH_CONVERT));
|
||||
ASSERT(INT_GET(free->bests[findex], ARCH_CONVERT) != NULLDATAOFF);
|
||||
ASSERT(INT_GET(free->bests[findex], ARCH_CONVERT) >= length);
|
||||
dbno = INT_GET(free->hdr.firstdb, ARCH_CONVERT) + findex;
|
||||
ASSERT(findex < be32_to_cpu(free->hdr.nvalid));
|
||||
ASSERT(be16_to_cpu(free->bests[findex]) != NULLDATAOFF);
|
||||
ASSERT(be16_to_cpu(free->bests[findex]) >= length);
|
||||
dbno = be32_to_cpu(free->hdr.firstdb) + findex;
|
||||
}
|
||||
/*
|
||||
* The data block looked at didn't have enough room.
|
||||
@ -1481,20 +1482,20 @@ xfs_dir2_node_addname_int(
|
||||
continue;
|
||||
}
|
||||
free = fbp->data;
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
|
||||
findex = 0;
|
||||
}
|
||||
/*
|
||||
* Look at the current free entry. Is it good enough?
|
||||
*/
|
||||
if (INT_GET(free->bests[findex], ARCH_CONVERT) != NULLDATAOFF &&
|
||||
INT_GET(free->bests[findex], ARCH_CONVERT) >= length)
|
||||
dbno = INT_GET(free->hdr.firstdb, ARCH_CONVERT) + findex;
|
||||
if (be16_to_cpu(free->bests[findex]) != NULLDATAOFF &&
|
||||
be16_to_cpu(free->bests[findex]) >= length)
|
||||
dbno = be32_to_cpu(free->hdr.firstdb) + findex;
|
||||
else {
|
||||
/*
|
||||
* Are we done with the freeblock?
|
||||
*/
|
||||
if (++findex == INT_GET(free->hdr.nvalid, ARCH_CONVERT)) {
|
||||
if (++findex == be32_to_cpu(free->hdr.nvalid)) {
|
||||
/*
|
||||
* Drop the block.
|
||||
*/
|
||||
@ -1608,15 +1609,15 @@ xfs_dir2_node_addname_int(
|
||||
* its first slot as our empty slot.
|
||||
*/
|
||||
free = fbp->data;
|
||||
INT_SET(free->hdr.magic, ARCH_CONVERT, XFS_DIR2_FREE_MAGIC);
|
||||
INT_SET(free->hdr.firstdb, ARCH_CONVERT,
|
||||
free->hdr.magic = cpu_to_be32(XFS_DIR2_FREE_MAGIC);
|
||||
free->hdr.firstdb = cpu_to_be32(
|
||||
(fbno - XFS_DIR2_FREE_FIRSTDB(mp)) *
|
||||
XFS_DIR2_MAX_FREE_BESTS(mp));
|
||||
free->hdr.nvalid = 0;
|
||||
free->hdr.nused = 0;
|
||||
} else {
|
||||
free = fbp->data;
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1627,20 +1628,20 @@ xfs_dir2_node_addname_int(
|
||||
* If it's after the end of the current entries in the
|
||||
* freespace block, extend that table.
|
||||
*/
|
||||
if (findex >= INT_GET(free->hdr.nvalid, ARCH_CONVERT)) {
|
||||
if (findex >= be32_to_cpu(free->hdr.nvalid)) {
|
||||
ASSERT(findex < XFS_DIR2_MAX_FREE_BESTS(mp));
|
||||
INT_SET(free->hdr.nvalid, ARCH_CONVERT, findex + 1);
|
||||
free->hdr.nvalid = cpu_to_be32(findex + 1);
|
||||
/*
|
||||
* Tag new entry so nused will go up.
|
||||
*/
|
||||
INT_SET(free->bests[findex], ARCH_CONVERT, NULLDATAOFF);
|
||||
free->bests[findex] = cpu_to_be16(NULLDATAOFF);
|
||||
}
|
||||
/*
|
||||
* If this entry was for an empty data block
|
||||
* (this should always be true) then update the header.
|
||||
*/
|
||||
if (INT_GET(free->bests[findex], ARCH_CONVERT) == NULLDATAOFF) {
|
||||
INT_MOD(free->hdr.nused, ARCH_CONVERT, +1);
|
||||
if (be16_to_cpu(free->bests[findex]) == NULLDATAOFF) {
|
||||
be32_add(&free->hdr.nused, 1);
|
||||
xfs_dir2_free_log_header(tp, fbp);
|
||||
}
|
||||
/*
|
||||
@ -1649,7 +1650,7 @@ xfs_dir2_node_addname_int(
|
||||
* change again.
|
||||
*/
|
||||
data = dbp->data;
|
||||
INT_COPY(free->bests[findex], data->hdr.bestfree[0].length, ARCH_CONVERT);
|
||||
free->bests[findex] = data->hdr.bestfree[0].length;
|
||||
logfree = 1;
|
||||
}
|
||||
/*
|
||||
@ -1677,12 +1678,12 @@ xfs_dir2_node_addname_int(
|
||||
data = dbp->data;
|
||||
logfree = 0;
|
||||
}
|
||||
ASSERT(INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT) >= length);
|
||||
ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) >= length);
|
||||
/*
|
||||
* Point to the existing unused space.
|
||||
*/
|
||||
dup = (xfs_dir2_data_unused_t *)
|
||||
((char *)data + INT_GET(data->hdr.bestfree[0].offset, ARCH_CONVERT));
|
||||
((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset));
|
||||
needscan = needlog = 0;
|
||||
/*
|
||||
* Mark the first part of the unused space, inuse for us.
|
||||
@ -1698,7 +1699,7 @@ xfs_dir2_node_addname_int(
|
||||
dep->namelen = args->namelen;
|
||||
memcpy(dep->name, args->name, dep->namelen);
|
||||
tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep);
|
||||
INT_SET(*tagp, ARCH_CONVERT, (xfs_dir2_data_off_t)((char *)dep - (char *)data));
|
||||
*tagp = cpu_to_be16((char *)dep - (char *)data);
|
||||
xfs_dir2_data_log_entry(tp, dbp, dep);
|
||||
/*
|
||||
* Rescan the block for bestfree if needed.
|
||||
@ -1713,8 +1714,8 @@ xfs_dir2_node_addname_int(
|
||||
/*
|
||||
* If the freespace entry is now wrong, update it.
|
||||
*/
|
||||
if (INT_GET(free->bests[findex], ARCH_CONVERT) != INT_GET(data->hdr.bestfree[0].length, ARCH_CONVERT)) {
|
||||
INT_COPY(free->bests[findex], data->hdr.bestfree[0].length, ARCH_CONVERT);
|
||||
if (be16_to_cpu(free->bests[findex]) != be16_to_cpu(data->hdr.bestfree[0].length)) {
|
||||
free->bests[findex] = data->hdr.bestfree[0].length;
|
||||
logfree = 1;
|
||||
}
|
||||
/*
|
||||
@ -1731,7 +1732,7 @@ xfs_dir2_node_addname_int(
|
||||
* Return the data block and offset in args, then drop the data block.
|
||||
*/
|
||||
args->blkno = (xfs_dablk_t)dbno;
|
||||
args->index = INT_GET(*tagp, ARCH_CONVERT);
|
||||
args->index = be16_to_cpu(*tagp);
|
||||
xfs_da_buf_done(dbp);
|
||||
return 0;
|
||||
}
|
||||
@ -1900,10 +1901,10 @@ xfs_dir2_node_replace(
|
||||
* Point to the data entry.
|
||||
*/
|
||||
data = state->extrablk.bp->data;
|
||||
ASSERT(INT_GET(data->hdr.magic, ARCH_CONVERT) == XFS_DIR2_DATA_MAGIC);
|
||||
ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC);
|
||||
dep = (xfs_dir2_data_entry_t *)
|
||||
((char *)data +
|
||||
XFS_DIR2_DATAPTR_TO_OFF(state->mp, INT_GET(lep->address, ARCH_CONVERT)));
|
||||
XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address)));
|
||||
ASSERT(inum != INT_GET(dep->inumber, ARCH_CONVERT));
|
||||
/*
|
||||
* Fill in the new inode number and log the entry.
|
||||
@ -1966,11 +1967,11 @@ xfs_dir2_node_trim_free(
|
||||
return 0;
|
||||
}
|
||||
free = bp->data;
|
||||
ASSERT(INT_GET(free->hdr.magic, ARCH_CONVERT) == XFS_DIR2_FREE_MAGIC);
|
||||
ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC);
|
||||
/*
|
||||
* If there are used entries, there's nothing to do.
|
||||
*/
|
||||
if (INT_GET(free->hdr.nused, ARCH_CONVERT) > 0) {
|
||||
if (be32_to_cpu(free->hdr.nused) > 0) {
|
||||
xfs_da_brelse(tp, bp);
|
||||
*rvalp = 0;
|
||||
return 0;
|
||||
|
@ -41,15 +41,15 @@ struct xfs_trans;
|
||||
#define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */
|
||||
|
||||
typedef struct xfs_dir2_free_hdr {
|
||||
__uint32_t magic; /* XFS_DIR2_FREE_MAGIC */
|
||||
__int32_t firstdb; /* db of first entry */
|
||||
__int32_t nvalid; /* count of valid entries */
|
||||
__int32_t nused; /* count of used entries */
|
||||
__be32 magic; /* XFS_DIR2_FREE_MAGIC */
|
||||
__be32 firstdb; /* db of first entry */
|
||||
__be32 nvalid; /* count of valid entries */
|
||||
__be32 nused; /* count of used entries */
|
||||
} xfs_dir2_free_hdr_t;
|
||||
|
||||
typedef struct xfs_dir2_free {
|
||||
xfs_dir2_free_hdr_t hdr; /* block header */
|
||||
xfs_dir2_data_off_t bests[1]; /* best free counts */
|
||||
__be16 bests[1]; /* best free counts */
|
||||
/* unused entries are -1 */
|
||||
} xfs_dir2_free_t;
|
||||
|
||||
|
@ -98,8 +98,8 @@ xfs_dir2_block_sfsize(
|
||||
/*
|
||||
* Iterate over the block's data entries by using the leaf pointers.
|
||||
*/
|
||||
for (i = 0; i < INT_GET(btp->count, ARCH_CONVERT); i++) {
|
||||
if ((addr = INT_GET(blp[i].address, ARCH_CONVERT)) == XFS_DIR2_NULL_DATAPTR)
|
||||
for (i = 0; i < be32_to_cpu(btp->count); i++) {
|
||||
if ((addr = be32_to_cpu(blp[i].address)) == XFS_DIR2_NULL_DATAPTR)
|
||||
continue;
|
||||
/*
|
||||
* Calculate the pointer to the entry at hand.
|
||||
@ -220,8 +220,8 @@ xfs_dir2_block_to_sf(
|
||||
* If it's unused, just skip over it.
|
||||
*/
|
||||
dup = (xfs_dir2_data_unused_t *)ptr;
|
||||
if (INT_GET(dup->freetag, ARCH_CONVERT) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
ptr += INT_GET(dup->length, ARCH_CONVERT);
|
||||
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
|
||||
ptr += be16_to_cpu(dup->length);
|
||||
continue;
|
||||
}
|
||||
dep = (xfs_dir2_data_entry_t *)ptr;
|
||||
|
@ -176,7 +176,7 @@ xfs_dir_shortform_addname(xfs_da_args_t *args)
|
||||
ASSERT(dp->i_df.if_u1.if_data != NULL);
|
||||
sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
|
||||
sfe = &sf->list[0];
|
||||
for (i = INT_GET(sf->hdr.count, ARCH_CONVERT)-1; i >= 0; i--) {
|
||||
for (i = sf->hdr.count-1; i >= 0; i--) {
|
||||
if (sfe->namelen == args->namelen &&
|
||||
args->name[0] == sfe->name[0] &&
|
||||
memcmp(args->name, sfe->name, args->namelen) == 0)
|
||||
@ -193,7 +193,7 @@ xfs_dir_shortform_addname(xfs_da_args_t *args)
|
||||
XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber);
|
||||
sfe->namelen = args->namelen;
|
||||
memcpy(sfe->name, args->name, sfe->namelen);
|
||||
INT_MOD(sf->hdr.count, ARCH_CONVERT, +1);
|
||||
sf->hdr.count++;
|
||||
|
||||
dp->i_d.di_size += size;
|
||||
xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA);
|
||||
@ -227,7 +227,7 @@ xfs_dir_shortform_removename(xfs_da_args_t *args)
|
||||
base = sizeof(xfs_dir_sf_hdr_t);
|
||||
sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
|
||||
sfe = &sf->list[0];
|
||||
for (i = INT_GET(sf->hdr.count, ARCH_CONVERT)-1; i >= 0; i--) {
|
||||
for (i = sf->hdr.count-1; i >= 0; i--) {
|
||||
size = XFS_DIR_SF_ENTSIZE_BYENTRY(sfe);
|
||||
if (sfe->namelen == args->namelen &&
|
||||
sfe->name[0] == args->name[0] &&
|
||||
@ -245,7 +245,7 @@ xfs_dir_shortform_removename(xfs_da_args_t *args)
|
||||
memmove(&((char *)sf)[base], &((char *)sf)[base+size],
|
||||
dp->i_d.di_size - (base+size));
|
||||
}
|
||||
INT_MOD(sf->hdr.count, ARCH_CONVERT, -1);
|
||||
sf->hdr.count--;
|
||||
|
||||
xfs_idata_realloc(dp, -size, XFS_DATA_FORK);
|
||||
dp->i_d.di_size -= size;
|
||||
@ -288,7 +288,7 @@ xfs_dir_shortform_lookup(xfs_da_args_t *args)
|
||||
return(XFS_ERROR(EEXIST));
|
||||
}
|
||||
sfe = &sf->list[0];
|
||||
for (i = INT_GET(sf->hdr.count, ARCH_CONVERT)-1; i >= 0; i--) {
|
||||
for (i = sf->hdr.count-1; i >= 0; i--) {
|
||||
if (sfe->namelen == args->namelen &&
|
||||
sfe->name[0] == args->name[0] &&
|
||||
memcmp(args->name, sfe->name, args->namelen) == 0) {
|
||||
@ -375,7 +375,7 @@ xfs_dir_shortform_to_leaf(xfs_da_args_t *iargs)
|
||||
goto out;
|
||||
|
||||
sfe = &sf->list[0];
|
||||
for (i = 0; i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
|
||||
for (i = 0; i < sf->hdr.count; i++) {
|
||||
args.name = (char *)(sfe->name);
|
||||
args.namelen = sfe->namelen;
|
||||
args.hashval = xfs_da_hashname((char *)(sfe->name),
|
||||
@ -428,7 +428,7 @@ xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp,
|
||||
sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data;
|
||||
cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset);
|
||||
want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset);
|
||||
nsbuf = INT_GET(sf->hdr.count, ARCH_CONVERT) + 2;
|
||||
nsbuf = sf->hdr.count + 2;
|
||||
sbsize = (nsbuf + 1) * sizeof(*sbuf);
|
||||
sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP);
|
||||
|
||||
@ -460,8 +460,7 @@ xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp,
|
||||
/*
|
||||
* Scan the directory data for the rest of the entries.
|
||||
*/
|
||||
for (i = 0, sfe = &sf->list[0];
|
||||
i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) {
|
||||
for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
|
||||
|
||||
if (unlikely(
|
||||
((char *)sfe < (char *)sf) ||
|
||||
@ -600,7 +599,7 @@ xfs_dir_shortform_replace(xfs_da_args_t *args)
|
||||
}
|
||||
ASSERT(args->namelen != 1 || args->name[0] != '.');
|
||||
sfe = &sf->list[0];
|
||||
for (i = INT_GET(sf->hdr.count, ARCH_CONVERT)-1; i >= 0; i--) {
|
||||
for (i = sf->hdr.count-1; i >= 0; i--) {
|
||||
if (sfe->namelen == args->namelen &&
|
||||
sfe->name[0] == args->name[0] &&
|
||||
memcmp(args->name, sfe->name, args->namelen) == 0) {
|
||||
@ -644,7 +643,7 @@ xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs)
|
||||
ASSERT(bp != NULL);
|
||||
memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount));
|
||||
leaf = (xfs_dir_leafblock_t *)tmpbuffer;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
memset(bp->data, 0, XFS_LBSIZE(dp->i_mount));
|
||||
|
||||
/*
|
||||
@ -742,11 +741,13 @@ xfs_dir_leaf_to_node(xfs_da_args_t *args)
|
||||
}
|
||||
node = bp1->data;
|
||||
leaf = bp2->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
INT_SET(node->btree[0].hashval, ARCH_CONVERT, INT_GET(leaf->entries[ INT_GET(leaf->hdr.count, ARCH_CONVERT)-1 ].hashval, ARCH_CONVERT));
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
node->btree[0].hashval = cpu_to_be32(
|
||||
INT_GET(leaf->entries[
|
||||
INT_GET(leaf->hdr.count, ARCH_CONVERT)-1].hashval, ARCH_CONVERT));
|
||||
xfs_da_buf_done(bp2);
|
||||
INT_SET(node->btree[0].before, ARCH_CONVERT, blkno);
|
||||
INT_SET(node->hdr.count, ARCH_CONVERT, 1);
|
||||
node->btree[0].before = cpu_to_be32(blkno);
|
||||
node->hdr.count = cpu_to_be16(1);
|
||||
xfs_da_log_buf(args->trans, bp1,
|
||||
XFS_DA_LOGRANGE(node, &node->btree[0], sizeof(node->btree[0])));
|
||||
xfs_da_buf_done(bp1);
|
||||
@ -781,7 +782,7 @@ xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp)
|
||||
leaf = bp->data;
|
||||
memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount));
|
||||
hdr = &leaf->hdr;
|
||||
INT_SET(hdr->info.magic, ARCH_CONVERT, XFS_DIR_LEAF_MAGIC);
|
||||
hdr->info.magic = cpu_to_be16(XFS_DIR_LEAF_MAGIC);
|
||||
INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount));
|
||||
if (!hdr->firstused)
|
||||
INT_SET(hdr->firstused, ARCH_CONVERT, XFS_LBSIZE(dp->i_mount) - 1);
|
||||
@ -860,7 +861,7 @@ xfs_dir_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index)
|
||||
int tablesize, entsize, sum, i, tmp, error;
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT((index >= 0) && (index <= INT_GET(leaf->hdr.count, ARCH_CONVERT)));
|
||||
hdr = &leaf->hdr;
|
||||
entsize = XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen);
|
||||
@ -940,7 +941,7 @@ xfs_dir_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int index,
|
||||
int tmp, i;
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
hdr = &leaf->hdr;
|
||||
ASSERT((mapindex >= 0) && (mapindex < XFS_DIR_LEAF_MAPSIZE));
|
||||
ASSERT((index >= 0) && (index <= INT_GET(hdr->count, ARCH_CONVERT)));
|
||||
@ -1097,8 +1098,8 @@ xfs_dir_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
|
||||
ASSERT(blk2->magic == XFS_DIR_LEAF_MAGIC);
|
||||
leaf1 = blk1->bp->data;
|
||||
leaf2 = blk2->bp->data;
|
||||
ASSERT(INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
|
||||
/*
|
||||
* Check ordering of blocks, reverse if it makes things simpler.
|
||||
@ -1325,7 +1326,7 @@ xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action)
|
||||
*/
|
||||
blk = &state->path.blk[ state->path.active-1 ];
|
||||
info = blk->bp->data;
|
||||
ASSERT(INT_GET(info->magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(info->magic) == XFS_DIR_LEAF_MAGIC);
|
||||
leaf = (xfs_dir_leafblock_t *)info;
|
||||
count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
|
||||
bytes = (uint)sizeof(xfs_dir_leaf_hdr_t) +
|
||||
@ -1348,7 +1349,7 @@ xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action)
|
||||
* Make altpath point to the block we want to keep and
|
||||
* path point to the block we want to drop (this one).
|
||||
*/
|
||||
forward = info->forw;
|
||||
forward = (info->forw != 0);
|
||||
memcpy(&state->altpath, &state->path, sizeof(state->path));
|
||||
error = xfs_da_path_shift(state, &state->altpath, forward,
|
||||
0, &retval);
|
||||
@ -1369,12 +1370,12 @@ xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action)
|
||||
* We prefer coalescing with the lower numbered sibling so as
|
||||
* to shrink a directory over time.
|
||||
*/
|
||||
forward = (INT_GET(info->forw, ARCH_CONVERT) < INT_GET(info->back, ARCH_CONVERT)); /* start with smaller blk num */
|
||||
forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); /* start with smaller blk num */
|
||||
for (i = 0; i < 2; forward = !forward, i++) {
|
||||
if (forward)
|
||||
blkno = INT_GET(info->forw, ARCH_CONVERT);
|
||||
blkno = be32_to_cpu(info->forw);
|
||||
else
|
||||
blkno = INT_GET(info->back, ARCH_CONVERT);
|
||||
blkno = be32_to_cpu(info->back);
|
||||
if (blkno == 0)
|
||||
continue;
|
||||
error = xfs_da_read_buf(state->args->trans, state->args->dp,
|
||||
@ -1389,7 +1390,7 @@ xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action)
|
||||
bytes = state->blocksize - (state->blocksize>>2);
|
||||
bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
count += INT_GET(leaf->hdr.count, ARCH_CONVERT);
|
||||
bytes -= INT_GET(leaf->hdr.namebytes, ARCH_CONVERT);
|
||||
bytes -= count * ((uint)sizeof(xfs_dir_leaf_name_t) - 1);
|
||||
@ -1447,7 +1448,7 @@ xfs_dir_leaf_remove(xfs_trans_t *trans, xfs_dabuf_t *bp, int index)
|
||||
xfs_mount_t *mp;
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
hdr = &leaf->hdr;
|
||||
mp = trans->t_mountp;
|
||||
ASSERT((INT_GET(hdr->count, ARCH_CONVERT) > 0) && (INT_GET(hdr->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
|
||||
@ -1599,8 +1600,8 @@ xfs_dir_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk,
|
||||
ASSERT(save_blk->magic == XFS_DIR_LEAF_MAGIC);
|
||||
drop_leaf = drop_blk->bp->data;
|
||||
save_leaf = save_blk->bp->data;
|
||||
ASSERT(INT_GET(drop_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(INT_GET(save_leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
drop_hdr = &drop_leaf->hdr;
|
||||
save_hdr = &save_leaf->hdr;
|
||||
|
||||
@ -1695,7 +1696,7 @@ xfs_dir_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args, int *index)
|
||||
xfs_dahash_t hashval;
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(INT_GET(leaf->hdr.count, ARCH_CONVERT) < (XFS_LBSIZE(args->dp->i_mount)/8));
|
||||
|
||||
/*
|
||||
@ -1782,8 +1783,8 @@ xfs_dir_leaf_moveents(xfs_dir_leafblock_t *leaf_s, int start_s,
|
||||
/*
|
||||
* Set up environment.
|
||||
*/
|
||||
ASSERT(INT_GET(leaf_s->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(INT_GET(leaf_d->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
hdr_s = &leaf_s->hdr;
|
||||
hdr_d = &leaf_d->hdr;
|
||||
ASSERT((INT_GET(hdr_s->count, ARCH_CONVERT) > 0) && (INT_GET(hdr_s->count, ARCH_CONVERT) < (XFS_LBSIZE(mp)/8)));
|
||||
@ -1883,8 +1884,8 @@ xfs_dir_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp)
|
||||
|
||||
leaf1 = leaf1_bp->data;
|
||||
leaf2 = leaf2_bp->data;
|
||||
ASSERT((INT_GET(leaf1->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC) &&
|
||||
(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC));
|
||||
ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC) &&
|
||||
(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC));
|
||||
if ((INT_GET(leaf1->hdr.count, ARCH_CONVERT) > 0) && (INT_GET(leaf2->hdr.count, ARCH_CONVERT) > 0) &&
|
||||
((INT_GET(leaf2->entries[ 0 ].hashval, ARCH_CONVERT) <
|
||||
INT_GET(leaf1->entries[ 0 ].hashval, ARCH_CONVERT)) ||
|
||||
@ -1904,7 +1905,7 @@ xfs_dir_leaf_lasthash(xfs_dabuf_t *bp, int *count)
|
||||
xfs_dir_leafblock_t *leaf;
|
||||
|
||||
leaf = bp->data;
|
||||
ASSERT(INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) == XFS_DIR_LEAF_MAGIC);
|
||||
ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC);
|
||||
if (count)
|
||||
*count = INT_GET(leaf->hdr.count, ARCH_CONVERT);
|
||||
if (!leaf->hdr.count)
|
||||
@ -1940,7 +1941,7 @@ xfs_dir_leaf_getdents_int(
|
||||
|
||||
mp = dp->i_mount;
|
||||
leaf = bp->data;
|
||||
if (INT_GET(leaf->hdr.info.magic, ARCH_CONVERT) != XFS_DIR_LEAF_MAGIC) {
|
||||
if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) {
|
||||
*eobp = 1;
|
||||
return XFS_ERROR(ENOENT); /* XXX wrong code */
|
||||
}
|
||||
@ -1992,7 +1993,7 @@ xfs_dir_leaf_getdents_int(
|
||||
|
||||
if (i == INT_GET(leaf->hdr.count, ARCH_CONVERT)) {
|
||||
xfs_dir_trace_g_du("leaf: hash not found", dp, uio);
|
||||
if (!INT_GET(leaf->hdr.info.forw, ARCH_CONVERT))
|
||||
if (!leaf->hdr.info.forw)
|
||||
uio->uio_offset =
|
||||
XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH);
|
||||
/*
|
||||
@ -2047,8 +2048,7 @@ xfs_dir_leaf_getdents_int(
|
||||
xfs_dir_trace_g_duc("leaf: middle cookie ",
|
||||
dp, uio, p.cook.o);
|
||||
|
||||
} else if ((thishash = INT_GET(leaf->hdr.info.forw,
|
||||
ARCH_CONVERT))) {
|
||||
} else if ((thishash = be32_to_cpu(leaf->hdr.info.forw))) {
|
||||
xfs_dabuf_t *bp2;
|
||||
xfs_dir_leafblock_t *leaf2;
|
||||
|
||||
@ -2064,9 +2064,9 @@ xfs_dir_leaf_getdents_int(
|
||||
leaf2 = bp2->data;
|
||||
|
||||
if (unlikely(
|
||||
(INT_GET(leaf2->hdr.info.magic, ARCH_CONVERT)
|
||||
(be16_to_cpu(leaf2->hdr.info.magic)
|
||||
!= XFS_DIR_LEAF_MAGIC)
|
||||
|| (INT_GET(leaf2->hdr.info.back, ARCH_CONVERT)
|
||||
|| (be32_to_cpu(leaf2->hdr.info.back)
|
||||
!= bno))) { /* GROT */
|
||||
XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)",
|
||||
XFS_ERRLEVEL_LOW, mp,
|
||||
|
@ -35,19 +35,21 @@ typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t;
|
||||
* and the elements much be memcpy'd out into a work area to get correct
|
||||
* alignment for the inode number fields.
|
||||
*/
|
||||
typedef struct xfs_dir_sf_hdr { /* constant-structure header block */
|
||||
xfs_dir_ino_t parent; /* parent dir inode number */
|
||||
__uint8_t count; /* count of active entries */
|
||||
} xfs_dir_sf_hdr_t;
|
||||
|
||||
typedef struct xfs_dir_sf_entry {
|
||||
xfs_dir_ino_t inumber; /* referenced inode number */
|
||||
__uint8_t namelen; /* actual length of name (no NULL) */
|
||||
__uint8_t name[1]; /* name */
|
||||
} xfs_dir_sf_entry_t;
|
||||
|
||||
typedef struct xfs_dir_shortform {
|
||||
struct xfs_dir_sf_hdr { /* constant-structure header block */
|
||||
xfs_dir_ino_t parent; /* parent dir inode number */
|
||||
__uint8_t count; /* count of active entries */
|
||||
} hdr;
|
||||
struct xfs_dir_sf_entry {
|
||||
xfs_dir_ino_t inumber; /* referenced inode number */
|
||||
__uint8_t namelen; /* actual length of name (no NULL) */
|
||||
__uint8_t name[1]; /* name */
|
||||
} list[1]; /* variable sized array */
|
||||
xfs_dir_sf_hdr_t hdr;
|
||||
xfs_dir_sf_entry_t list[1]; /* variable sized array */
|
||||
} xfs_dir_shortform_t;
|
||||
typedef struct xfs_dir_sf_hdr xfs_dir_sf_hdr_t;
|
||||
typedef struct xfs_dir_sf_entry xfs_dir_sf_entry_t;
|
||||
|
||||
/*
|
||||
* We generate this then sort it, so that readdirs are returned in
|
||||
|
@ -191,14 +191,4 @@ typedef enum {
|
||||
|
||||
extern struct bhv_vfsops xfs_dmops;
|
||||
|
||||
#ifdef CONFIG_XFS_DMAPI
|
||||
void xfs_dm_init(struct file_system_type *);
|
||||
void xfs_dm_exit(struct file_system_type *);
|
||||
#define XFS_DM_INIT(fstype) xfs_dm_init(fstype)
|
||||
#define XFS_DM_EXIT(fstype) xfs_dm_exit(fstype)
|
||||
#else
|
||||
#define XFS_DM_INIT(fstype)
|
||||
#define XFS_DM_EXIT(fstype)
|
||||
#endif
|
||||
|
||||
#endif /* __XFS_DMAPI_H__ */
|
||||
|
@ -462,6 +462,7 @@ xfs_fs_counts(
|
||||
{
|
||||
unsigned long s;
|
||||
|
||||
xfs_icsb_sync_counters_lazy(mp);
|
||||
s = XFS_SB_LOCK(mp);
|
||||
cnt->freedata = mp->m_sb.sb_fdblocks;
|
||||
cnt->freertx = mp->m_sb.sb_frextents;
|
||||
|
@ -138,8 +138,6 @@ xfs_ialloc_ag_alloc(
|
||||
int version; /* inode version number to use */
|
||||
int isaligned; /* inode allocation at stripe unit */
|
||||
/* boundary */
|
||||
xfs_dinode_core_t dic; /* a dinode_core to copy to new */
|
||||
/* inodes */
|
||||
|
||||
args.tp = tp;
|
||||
args.mp = tp->t_mountp;
|
||||
@ -250,10 +248,6 @@ xfs_ialloc_ag_alloc(
|
||||
else
|
||||
version = XFS_DINODE_VERSION_1;
|
||||
|
||||
memset(&dic, 0, sizeof(xfs_dinode_core_t));
|
||||
INT_SET(dic.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC);
|
||||
INT_SET(dic.di_version, ARCH_CONVERT, version);
|
||||
|
||||
for (j = 0; j < nbufs; j++) {
|
||||
/*
|
||||
* Get the block.
|
||||
@ -266,12 +260,13 @@ xfs_ialloc_ag_alloc(
|
||||
ASSERT(fbuf);
|
||||
ASSERT(!XFS_BUF_GETERROR(fbuf));
|
||||
/*
|
||||
* Loop over the inodes in this buffer.
|
||||
* Set initial values for the inodes in this buffer.
|
||||
*/
|
||||
|
||||
xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);
|
||||
for (i = 0; i < ninodes; i++) {
|
||||
free = XFS_MAKE_IPTR(args.mp, fbuf, i);
|
||||
memcpy(&(free->di_core), &dic, sizeof(xfs_dinode_core_t));
|
||||
INT_SET(free->di_core.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC);
|
||||
INT_SET(free->di_core.di_version, ARCH_CONVERT, version);
|
||||
INT_SET(free->di_next_unlinked, ARCH_CONVERT, NULLAGINO);
|
||||
xfs_ialloc_log_di(tp, fbuf, i,
|
||||
XFS_DI_CORE_BITS | XFS_DI_NEXT_UNLINKED);
|
||||
|
@ -258,7 +258,7 @@ again:
|
||||
goto finish_inode;
|
||||
|
||||
} else if (vp != inode_vp) {
|
||||
struct inode *inode = LINVFS_GET_IP(inode_vp);
|
||||
struct inode *inode = vn_to_inode(inode_vp);
|
||||
|
||||
/* The inode is being torn down, pause and
|
||||
* try again.
|
||||
@ -495,7 +495,7 @@ retry:
|
||||
if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) {
|
||||
xfs_inode_t *ip;
|
||||
|
||||
vp = LINVFS_GET_VP(inode);
|
||||
vp = vn_from_inode(inode);
|
||||
if (inode->i_state & I_NEW) {
|
||||
vn_initialize(inode);
|
||||
error = xfs_iget_core(vp, mp, tp, ino, flags,
|
||||
@ -617,7 +617,7 @@ xfs_iput_new(xfs_inode_t *ip,
|
||||
uint lock_flags)
|
||||
{
|
||||
vnode_t *vp = XFS_ITOV(ip);
|
||||
struct inode *inode = LINVFS_GET_IP(vp);
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
|
||||
vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
|
||||
|
||||
|
1303
fs/xfs/xfs_inode.c
1303
fs/xfs/xfs_inode.c
File diff suppressed because it is too large
Load Diff
@ -24,11 +24,38 @@
|
||||
#define XFS_DATA_FORK 0
|
||||
#define XFS_ATTR_FORK 1
|
||||
|
||||
/*
|
||||
* The following xfs_ext_irec_t struct introduces a second (top) level
|
||||
* to the in-core extent allocation scheme. These structs are allocated
|
||||
* in a contiguous block, creating an indirection array where each entry
|
||||
* (irec) contains a pointer to a buffer of in-core extent records which
|
||||
* it manages. Each extent buffer is 4k in size, since 4k is the system
|
||||
* page size on Linux i386 and systems with larger page sizes don't seem
|
||||
* to gain much, if anything, by using their native page size as the
|
||||
* extent buffer size. Also, using 4k extent buffers everywhere provides
|
||||
* a consistent interface for CXFS across different platforms.
|
||||
*
|
||||
* There is currently no limit on the number of irec's (extent lists)
|
||||
* allowed, so heavily fragmented files may require an indirection array
|
||||
* which spans multiple system pages of memory. The number of extents
|
||||
* which would require this amount of contiguous memory is very large
|
||||
* and should not cause problems in the foreseeable future. However,
|
||||
* if the memory needed for the contiguous array ever becomes a problem,
|
||||
* it is possible that a third level of indirection may be required.
|
||||
*/
|
||||
typedef struct xfs_ext_irec {
|
||||
xfs_bmbt_rec_t *er_extbuf; /* block of extent records */
|
||||
xfs_extnum_t er_extoff; /* extent offset in file */
|
||||
xfs_extnum_t er_extcount; /* number of extents in page/block */
|
||||
} xfs_ext_irec_t;
|
||||
|
||||
/*
|
||||
* File incore extent information, present for each of data & attr forks.
|
||||
*/
|
||||
#define XFS_INLINE_EXTS 2
|
||||
#define XFS_INLINE_DATA 32
|
||||
#define XFS_IEXT_BUFSZ 4096
|
||||
#define XFS_LINEAR_EXTS (XFS_IEXT_BUFSZ / (uint)sizeof(xfs_bmbt_rec_t))
|
||||
#define XFS_INLINE_EXTS 2
|
||||
#define XFS_INLINE_DATA 32
|
||||
typedef struct xfs_ifork {
|
||||
int if_bytes; /* bytes in if_u1 */
|
||||
int if_real_bytes; /* bytes allocated in if_u1 */
|
||||
@ -39,6 +66,7 @@ typedef struct xfs_ifork {
|
||||
xfs_extnum_t if_lastex; /* last if_extents used */
|
||||
union {
|
||||
xfs_bmbt_rec_t *if_extents; /* linear map file exts */
|
||||
xfs_ext_irec_t *if_ext_irec; /* irec map file exts */
|
||||
char *if_data; /* inline file data */
|
||||
} if_u1;
|
||||
union {
|
||||
@ -61,20 +89,16 @@ typedef struct xfs_ifork {
|
||||
/*
|
||||
* Per-fork incore inode flags.
|
||||
*/
|
||||
#define XFS_IFINLINE 0x0001 /* Inline data is read in */
|
||||
#define XFS_IFEXTENTS 0x0002 /* All extent pointers are read in */
|
||||
#define XFS_IFBROOT 0x0004 /* i_broot points to the bmap b-tree root */
|
||||
#define XFS_IFINLINE 0x01 /* Inline data is read in */
|
||||
#define XFS_IFEXTENTS 0x02 /* All extent pointers are read in */
|
||||
#define XFS_IFBROOT 0x04 /* i_broot points to the bmap b-tree root */
|
||||
#define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */
|
||||
|
||||
/*
|
||||
* Flags for xfs_imap() and xfs_dilocate().
|
||||
* Flags for xfs_itobp(), xfs_imap() and xfs_dilocate().
|
||||
*/
|
||||
#define XFS_IMAP_LOOKUP 0x1
|
||||
|
||||
/*
|
||||
* Maximum number of extent pointers in if_u1.if_extents.
|
||||
*/
|
||||
#define XFS_MAX_INCORE_EXTENTS 32768
|
||||
|
||||
#define XFS_IMAP_LOOKUP 0x1
|
||||
#define XFS_IMAP_BULKSTAT 0x2
|
||||
|
||||
#ifdef __KERNEL__
|
||||
struct bhv_desc;
|
||||
@ -398,7 +422,7 @@ int xfs_finish_reclaim_all(struct xfs_mount *, int);
|
||||
*/
|
||||
int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
|
||||
xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **,
|
||||
xfs_daddr_t);
|
||||
xfs_daddr_t, uint);
|
||||
int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
|
||||
xfs_inode_t **, xfs_daddr_t);
|
||||
int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
|
||||
@ -440,6 +464,32 @@ xfs_inode_t *xfs_vtoi(struct vnode *vp);
|
||||
|
||||
void xfs_synchronize_atime(xfs_inode_t *);
|
||||
|
||||
xfs_bmbt_rec_t *xfs_iext_get_ext(xfs_ifork_t *, xfs_extnum_t);
|
||||
void xfs_iext_insert(xfs_ifork_t *, xfs_extnum_t, xfs_extnum_t,
|
||||
xfs_bmbt_irec_t *);
|
||||
void xfs_iext_add(xfs_ifork_t *, xfs_extnum_t, int);
|
||||
void xfs_iext_add_indirect_multi(xfs_ifork_t *, int, xfs_extnum_t, int);
|
||||
void xfs_iext_remove(xfs_ifork_t *, xfs_extnum_t, int);
|
||||
void xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int);
|
||||
void xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int);
|
||||
void xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int);
|
||||
void xfs_iext_realloc_direct(xfs_ifork_t *, int);
|
||||
void xfs_iext_realloc_indirect(xfs_ifork_t *, int);
|
||||
void xfs_iext_indirect_to_direct(xfs_ifork_t *);
|
||||
void xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t);
|
||||
void xfs_iext_inline_to_direct(xfs_ifork_t *, int);
|
||||
void xfs_iext_destroy(xfs_ifork_t *);
|
||||
xfs_bmbt_rec_t *xfs_iext_bno_to_ext(xfs_ifork_t *, xfs_fileoff_t, int *);
|
||||
xfs_ext_irec_t *xfs_iext_bno_to_irec(xfs_ifork_t *, xfs_fileoff_t, int *);
|
||||
xfs_ext_irec_t *xfs_iext_idx_to_irec(xfs_ifork_t *, xfs_extnum_t *, int *, int);
|
||||
void xfs_iext_irec_init(xfs_ifork_t *);
|
||||
xfs_ext_irec_t *xfs_iext_irec_new(xfs_ifork_t *, int);
|
||||
void xfs_iext_irec_remove(xfs_ifork_t *, int);
|
||||
void xfs_iext_irec_compact(xfs_ifork_t *);
|
||||
void xfs_iext_irec_compact_pages(xfs_ifork_t *);
|
||||
void xfs_iext_irec_compact_full(xfs_ifork_t *);
|
||||
void xfs_iext_irec_update_extoffs(xfs_ifork_t *, int, int);
|
||||
|
||||
#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -76,7 +76,7 @@ xfs_iomap_enter_trace(
|
||||
(void *)((unsigned long)count),
|
||||
(void *)((unsigned long)((io->io_new_size >> 32) & 0xffffffff)),
|
||||
(void *)((unsigned long)(io->io_new_size & 0xffffffff)),
|
||||
(void *)NULL,
|
||||
(void *)((unsigned long)current_pid()),
|
||||
(void *)NULL,
|
||||
(void *)NULL,
|
||||
(void *)NULL,
|
||||
|
@ -562,7 +562,8 @@ xfs_bulkstat(
|
||||
if (bp)
|
||||
xfs_buf_relse(bp);
|
||||
error = xfs_itobp(mp, NULL, ip,
|
||||
&dip, &bp, bno);
|
||||
&dip, &bp, bno,
|
||||
XFS_IMAP_BULKSTAT);
|
||||
if (!error)
|
||||
clustidx = ip->i_boffset / mp->m_sb.sb_inodesize;
|
||||
kmem_zone_free(xfs_inode_zone, ip);
|
||||
@ -570,6 +571,8 @@ xfs_bulkstat(
|
||||
mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK,
|
||||
XFS_RANDOM_BULKSTAT_READ_CHUNK)) {
|
||||
bp = NULL;
|
||||
ubleft = 0;
|
||||
rval = error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3249,7 +3249,7 @@ xlog_recover_process_iunlinks(
|
||||
* next inode in the bucket.
|
||||
*/
|
||||
error = xfs_itobp(mp, NULL, ip, &dip,
|
||||
&ibp, 0);
|
||||
&ibp, 0, 0);
|
||||
ASSERT(error || (dip != NULL));
|
||||
}
|
||||
|
||||
|
@ -51,11 +51,32 @@ STATIC int xfs_uuid_mount(xfs_mount_t *);
|
||||
STATIC void xfs_uuid_unmount(xfs_mount_t *mp);
|
||||
STATIC void xfs_unmountfs_wait(xfs_mount_t *);
|
||||
|
||||
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
STATIC void xfs_icsb_destroy_counters(xfs_mount_t *);
|
||||
STATIC void xfs_icsb_balance_counter(xfs_mount_t *, xfs_sb_field_t, int);
|
||||
STATIC void xfs_icsb_sync_counters(xfs_mount_t *);
|
||||
STATIC int xfs_icsb_modify_counters(xfs_mount_t *, xfs_sb_field_t,
|
||||
int, int);
|
||||
STATIC int xfs_icsb_modify_counters_locked(xfs_mount_t *, xfs_sb_field_t,
|
||||
int, int);
|
||||
STATIC int xfs_icsb_disable_counter(xfs_mount_t *, xfs_sb_field_t);
|
||||
|
||||
#else
|
||||
|
||||
#define xfs_icsb_destroy_counters(mp) do { } while (0)
|
||||
#define xfs_icsb_balance_counter(mp, a, b) do { } while (0)
|
||||
#define xfs_icsb_sync_counters(mp) do { } while (0)
|
||||
#define xfs_icsb_modify_counters(mp, a, b, c) do { } while (0)
|
||||
#define xfs_icsb_modify_counters_locked(mp, a, b, c) do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
static const struct {
|
||||
short offset;
|
||||
short type; /* 0 = integer
|
||||
* 1 = binary / string (no translation)
|
||||
*/
|
||||
short offset;
|
||||
short type; /* 0 = integer
|
||||
* 1 = binary / string (no translation)
|
||||
*/
|
||||
} xfs_sb_info[] = {
|
||||
{ offsetof(xfs_sb_t, sb_magicnum), 0 },
|
||||
{ offsetof(xfs_sb_t, sb_blocksize), 0 },
|
||||
@ -113,7 +134,11 @@ xfs_mount_init(void)
|
||||
{
|
||||
xfs_mount_t *mp;
|
||||
|
||||
mp = kmem_zalloc(sizeof(*mp), KM_SLEEP);
|
||||
mp = kmem_zalloc(sizeof(xfs_mount_t), KM_SLEEP);
|
||||
|
||||
if (xfs_icsb_init_counters(mp)) {
|
||||
mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB;
|
||||
}
|
||||
|
||||
AIL_LOCKINIT(&mp->m_ail_lock, "xfs_ail");
|
||||
spinlock_init(&mp->m_sb_lock, "xfs_sb");
|
||||
@ -136,8 +161,8 @@ xfs_mount_init(void)
|
||||
*/
|
||||
void
|
||||
xfs_mount_free(
|
||||
xfs_mount_t *mp,
|
||||
int remove_bhv)
|
||||
xfs_mount_t *mp,
|
||||
int remove_bhv)
|
||||
{
|
||||
if (mp->m_ihash)
|
||||
xfs_ihash_free(mp);
|
||||
@ -177,6 +202,7 @@ xfs_mount_free(
|
||||
VFS_REMOVEBHV(vfsp, &mp->m_bhv);
|
||||
}
|
||||
|
||||
xfs_icsb_destroy_counters(mp);
|
||||
kmem_free(mp, sizeof(xfs_mount_t));
|
||||
}
|
||||
|
||||
@ -242,9 +268,12 @@ xfs_mount_validate_sb(
|
||||
sbp->sb_blocklog > XFS_MAX_BLOCKSIZE_LOG ||
|
||||
sbp->sb_inodesize < XFS_DINODE_MIN_SIZE ||
|
||||
sbp->sb_inodesize > XFS_DINODE_MAX_SIZE ||
|
||||
sbp->sb_inodelog < XFS_DINODE_MIN_LOG ||
|
||||
sbp->sb_inodelog > XFS_DINODE_MAX_LOG ||
|
||||
(sbp->sb_blocklog - sbp->sb_inodelog != sbp->sb_inopblog) ||
|
||||
(sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
|
||||
(sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
|
||||
sbp->sb_imax_pct > 100)) {
|
||||
(sbp->sb_imax_pct > 100 || sbp->sb_imax_pct < 1))) {
|
||||
cmn_err(CE_WARN, "XFS: SB sanity check 1 failed");
|
||||
XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(3)",
|
||||
XFS_ERRLEVEL_LOW, mp, sbp);
|
||||
@ -527,6 +556,10 @@ xfs_readsb(xfs_mount_t *mp)
|
||||
ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
|
||||
}
|
||||
|
||||
xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0);
|
||||
xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0);
|
||||
xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0);
|
||||
|
||||
mp->m_sb_bp = bp;
|
||||
xfs_buf_relse(bp);
|
||||
ASSERT(XFS_BUF_VALUSEMA(bp) > 0);
|
||||
@ -1154,6 +1187,9 @@ xfs_unmountfs_writesb(xfs_mount_t *mp)
|
||||
sbp = xfs_getsb(mp, 0);
|
||||
if (!(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY ||
|
||||
XFS_FORCED_SHUTDOWN(mp))) {
|
||||
|
||||
xfs_icsb_sync_counters(mp);
|
||||
|
||||
/*
|
||||
* mark shared-readonly if desired
|
||||
*/
|
||||
@ -1227,7 +1263,6 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
|
||||
|
||||
xfs_trans_log_buf(tp, bp, first, last);
|
||||
}
|
||||
|
||||
/*
|
||||
* xfs_mod_incore_sb_unlocked() is a utility routine common used to apply
|
||||
* a delta to a specified field in the in-core superblock. Simply
|
||||
@ -1237,7 +1272,7 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
|
||||
*
|
||||
* The SB_LOCK must be held when this routine is called.
|
||||
*/
|
||||
STATIC int
|
||||
int
|
||||
xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
|
||||
int delta, int rsvd)
|
||||
{
|
||||
@ -1406,9 +1441,26 @@ xfs_mod_incore_sb(xfs_mount_t *mp, xfs_sb_field_t field, int delta, int rsvd)
|
||||
unsigned long s;
|
||||
int status;
|
||||
|
||||
s = XFS_SB_LOCK(mp);
|
||||
status = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd);
|
||||
XFS_SB_UNLOCK(mp, s);
|
||||
/* check for per-cpu counters */
|
||||
switch (field) {
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
case XFS_SBS_ICOUNT:
|
||||
case XFS_SBS_IFREE:
|
||||
case XFS_SBS_FDBLOCKS:
|
||||
if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) {
|
||||
status = xfs_icsb_modify_counters(mp, field,
|
||||
delta, rsvd);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
default:
|
||||
s = XFS_SB_LOCK(mp);
|
||||
status = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd);
|
||||
XFS_SB_UNLOCK(mp, s);
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1445,8 +1497,26 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd)
|
||||
* from the loop so we'll fall into the undo loop
|
||||
* below.
|
||||
*/
|
||||
status = xfs_mod_incore_sb_unlocked(mp, msbp->msb_field,
|
||||
msbp->msb_delta, rsvd);
|
||||
switch (msbp->msb_field) {
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
case XFS_SBS_ICOUNT:
|
||||
case XFS_SBS_IFREE:
|
||||
case XFS_SBS_FDBLOCKS:
|
||||
if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) {
|
||||
status = xfs_icsb_modify_counters_locked(mp,
|
||||
msbp->msb_field,
|
||||
msbp->msb_delta, rsvd);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
default:
|
||||
status = xfs_mod_incore_sb_unlocked(mp,
|
||||
msbp->msb_field,
|
||||
msbp->msb_delta, rsvd);
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
break;
|
||||
}
|
||||
@ -1463,8 +1533,28 @@ xfs_mod_incore_sb_batch(xfs_mount_t *mp, xfs_mod_sb_t *msb, uint nmsb, int rsvd)
|
||||
if (status != 0) {
|
||||
msbp--;
|
||||
while (msbp >= msb) {
|
||||
status = xfs_mod_incore_sb_unlocked(mp,
|
||||
msbp->msb_field, -(msbp->msb_delta), rsvd);
|
||||
switch (msbp->msb_field) {
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
case XFS_SBS_ICOUNT:
|
||||
case XFS_SBS_IFREE:
|
||||
case XFS_SBS_FDBLOCKS:
|
||||
if (!(mp->m_flags & XFS_MOUNT_NO_PERCPU_SB)) {
|
||||
status =
|
||||
xfs_icsb_modify_counters_locked(mp,
|
||||
msbp->msb_field,
|
||||
-(msbp->msb_delta),
|
||||
rsvd);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
default:
|
||||
status = xfs_mod_incore_sb_unlocked(mp,
|
||||
msbp->msb_field,
|
||||
-(msbp->msb_delta),
|
||||
rsvd);
|
||||
break;
|
||||
}
|
||||
ASSERT(status == 0);
|
||||
msbp--;
|
||||
}
|
||||
@ -1577,3 +1667,525 @@ xfs_mount_log_sbunit(
|
||||
xfs_mod_sb(tp, fields);
|
||||
xfs_trans_commit(tp, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
/*
|
||||
* Per-cpu incore superblock counters
|
||||
*
|
||||
* Simple concept, difficult implementation
|
||||
*
|
||||
* Basically, replace the incore superblock counters with a distributed per cpu
|
||||
* counter for contended fields (e.g. free block count).
|
||||
*
|
||||
* Difficulties arise in that the incore sb is used for ENOSPC checking, and
|
||||
* hence needs to be accurately read when we are running low on space. Hence
|
||||
* there is a method to enable and disable the per-cpu counters based on how
|
||||
* much "stuff" is available in them.
|
||||
*
|
||||
* Basically, a counter is enabled if there is enough free resource to justify
|
||||
* running a per-cpu fast-path. If the per-cpu counter runs out (i.e. a local
|
||||
* ENOSPC), then we disable the counters to synchronise all callers and
|
||||
* re-distribute the available resources.
|
||||
*
|
||||
* If, once we redistributed the available resources, we still get a failure,
|
||||
* we disable the per-cpu counter and go through the slow path.
|
||||
*
|
||||
* The slow path is the current xfs_mod_incore_sb() function. This means that
|
||||
* when we disable a per-cpu counter, we need to drain it's resources back to
|
||||
* the global superblock. We do this after disabling the counter to prevent
|
||||
* more threads from queueing up on the counter.
|
||||
*
|
||||
* Essentially, this means that we still need a lock in the fast path to enable
|
||||
* synchronisation between the global counters and the per-cpu counters. This
|
||||
* is not a problem because the lock will be local to a CPU almost all the time
|
||||
* and have little contention except when we get to ENOSPC conditions.
|
||||
*
|
||||
* Basically, this lock becomes a barrier that enables us to lock out the fast
|
||||
* path while we do things like enabling and disabling counters and
|
||||
* synchronising the counters.
|
||||
*
|
||||
* Locking rules:
|
||||
*
|
||||
* 1. XFS_SB_LOCK() before picking up per-cpu locks
|
||||
* 2. per-cpu locks always picked up via for_each_online_cpu() order
|
||||
* 3. accurate counter sync requires XFS_SB_LOCK + per cpu locks
|
||||
* 4. modifying per-cpu counters requires holding per-cpu lock
|
||||
* 5. modifying global counters requires holding XFS_SB_LOCK
|
||||
* 6. enabling or disabling a counter requires holding the XFS_SB_LOCK
|
||||
* and _none_ of the per-cpu locks.
|
||||
*
|
||||
* Disabled counters are only ever re-enabled by a balance operation
|
||||
* that results in more free resources per CPU than a given threshold.
|
||||
* To ensure counters don't remain disabled, they are rebalanced when
|
||||
* the global resource goes above a higher threshold (i.e. some hysteresis
|
||||
* is present to prevent thrashing).
|
||||
*/
|
||||
|
||||
/*
|
||||
* hot-plug CPU notifier support.
|
||||
*
|
||||
* We cannot use the hotcpu_register() function because it does
|
||||
* not allow notifier instances. We need a notifier per filesystem
|
||||
* as we need to be able to identify the filesystem to balance
|
||||
* the counters out. This is acheived by having a notifier block
|
||||
* embedded in the xfs_mount_t and doing pointer magic to get the
|
||||
* mount pointer from the notifier block address.
|
||||
*/
|
||||
STATIC int
|
||||
xfs_icsb_cpu_notify(
|
||||
struct notifier_block *nfb,
|
||||
unsigned long action,
|
||||
void *hcpu)
|
||||
{
|
||||
xfs_icsb_cnts_t *cntp;
|
||||
xfs_mount_t *mp;
|
||||
int s;
|
||||
|
||||
mp = (xfs_mount_t *)container_of(nfb, xfs_mount_t, m_icsb_notifier);
|
||||
cntp = (xfs_icsb_cnts_t *)
|
||||
per_cpu_ptr(mp->m_sb_cnts, (unsigned long)hcpu);
|
||||
switch (action) {
|
||||
case CPU_UP_PREPARE:
|
||||
/* Easy Case - initialize the area and locks, and
|
||||
* then rebalance when online does everything else for us. */
|
||||
memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
|
||||
break;
|
||||
case CPU_ONLINE:
|
||||
xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, 0);
|
||||
xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, 0);
|
||||
xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, 0);
|
||||
break;
|
||||
case CPU_DEAD:
|
||||
/* Disable all the counters, then fold the dead cpu's
|
||||
* count into the total on the global superblock and
|
||||
* re-enable the counters. */
|
||||
s = XFS_SB_LOCK(mp);
|
||||
xfs_icsb_disable_counter(mp, XFS_SBS_ICOUNT);
|
||||
xfs_icsb_disable_counter(mp, XFS_SBS_IFREE);
|
||||
xfs_icsb_disable_counter(mp, XFS_SBS_FDBLOCKS);
|
||||
|
||||
mp->m_sb.sb_icount += cntp->icsb_icount;
|
||||
mp->m_sb.sb_ifree += cntp->icsb_ifree;
|
||||
mp->m_sb.sb_fdblocks += cntp->icsb_fdblocks;
|
||||
|
||||
memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
|
||||
|
||||
xfs_icsb_balance_counter(mp, XFS_SBS_ICOUNT, XFS_ICSB_SB_LOCKED);
|
||||
xfs_icsb_balance_counter(mp, XFS_SBS_IFREE, XFS_ICSB_SB_LOCKED);
|
||||
xfs_icsb_balance_counter(mp, XFS_SBS_FDBLOCKS, XFS_ICSB_SB_LOCKED);
|
||||
XFS_SB_UNLOCK(mp, s);
|
||||
break;
|
||||
}
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_icsb_init_counters(
|
||||
xfs_mount_t *mp)
|
||||
{
|
||||
xfs_icsb_cnts_t *cntp;
|
||||
int i;
|
||||
|
||||
mp->m_sb_cnts = alloc_percpu(xfs_icsb_cnts_t);
|
||||
if (mp->m_sb_cnts == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
mp->m_icsb_notifier.notifier_call = xfs_icsb_cpu_notify;
|
||||
mp->m_icsb_notifier.priority = 0;
|
||||
register_cpu_notifier(&mp->m_icsb_notifier);
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
|
||||
memset(cntp, 0, sizeof(xfs_icsb_cnts_t));
|
||||
}
|
||||
/*
|
||||
* start with all counters disabled so that the
|
||||
* initial balance kicks us off correctly
|
||||
*/
|
||||
mp->m_icsb_counters = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_icsb_destroy_counters(
|
||||
xfs_mount_t *mp)
|
||||
{
|
||||
if (mp->m_sb_cnts) {
|
||||
unregister_cpu_notifier(&mp->m_icsb_notifier);
|
||||
free_percpu(mp->m_sb_cnts);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC inline void
|
||||
xfs_icsb_lock_cntr(
|
||||
xfs_icsb_cnts_t *icsbp)
|
||||
{
|
||||
while (test_and_set_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags)) {
|
||||
ndelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC inline void
|
||||
xfs_icsb_unlock_cntr(
|
||||
xfs_icsb_cnts_t *icsbp)
|
||||
{
|
||||
clear_bit(XFS_ICSB_FLAG_LOCK, &icsbp->icsb_flags);
|
||||
}
|
||||
|
||||
|
||||
STATIC inline void
|
||||
xfs_icsb_lock_all_counters(
|
||||
xfs_mount_t *mp)
|
||||
{
|
||||
xfs_icsb_cnts_t *cntp;
|
||||
int i;
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
|
||||
xfs_icsb_lock_cntr(cntp);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC inline void
|
||||
xfs_icsb_unlock_all_counters(
|
||||
xfs_mount_t *mp)
|
||||
{
|
||||
xfs_icsb_cnts_t *cntp;
|
||||
int i;
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
|
||||
xfs_icsb_unlock_cntr(cntp);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_icsb_count(
|
||||
xfs_mount_t *mp,
|
||||
xfs_icsb_cnts_t *cnt,
|
||||
int flags)
|
||||
{
|
||||
xfs_icsb_cnts_t *cntp;
|
||||
int i;
|
||||
|
||||
memset(cnt, 0, sizeof(xfs_icsb_cnts_t));
|
||||
|
||||
if (!(flags & XFS_ICSB_LAZY_COUNT))
|
||||
xfs_icsb_lock_all_counters(mp);
|
||||
|
||||
for_each_online_cpu(i) {
|
||||
cntp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, i);
|
||||
cnt->icsb_icount += cntp->icsb_icount;
|
||||
cnt->icsb_ifree += cntp->icsb_ifree;
|
||||
cnt->icsb_fdblocks += cntp->icsb_fdblocks;
|
||||
}
|
||||
|
||||
if (!(flags & XFS_ICSB_LAZY_COUNT))
|
||||
xfs_icsb_unlock_all_counters(mp);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_icsb_counter_disabled(
|
||||
xfs_mount_t *mp,
|
||||
xfs_sb_field_t field)
|
||||
{
|
||||
ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS));
|
||||
return test_bit(field, &mp->m_icsb_counters);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_icsb_disable_counter(
|
||||
xfs_mount_t *mp,
|
||||
xfs_sb_field_t field)
|
||||
{
|
||||
xfs_icsb_cnts_t cnt;
|
||||
|
||||
ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS));
|
||||
|
||||
xfs_icsb_lock_all_counters(mp);
|
||||
if (!test_and_set_bit(field, &mp->m_icsb_counters)) {
|
||||
/* drain back to superblock */
|
||||
|
||||
xfs_icsb_count(mp, &cnt, XFS_ICSB_SB_LOCKED|XFS_ICSB_LAZY_COUNT);
|
||||
switch(field) {
|
||||
case XFS_SBS_ICOUNT:
|
||||
mp->m_sb.sb_icount = cnt.icsb_icount;
|
||||
break;
|
||||
case XFS_SBS_IFREE:
|
||||
mp->m_sb.sb_ifree = cnt.icsb_ifree;
|
||||
break;
|
||||
case XFS_SBS_FDBLOCKS:
|
||||
mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
xfs_icsb_unlock_all_counters(mp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_icsb_enable_counter(
|
||||
xfs_mount_t *mp,
|
||||
xfs_sb_field_t field,
|
||||
uint64_t count,
|
||||
uint64_t resid)
|
||||
{
|
||||
xfs_icsb_cnts_t *cntp;
|
||||
int i;
|
||||
|
||||
ASSERT((field >= XFS_SBS_ICOUNT) && (field <= XFS_SBS_FDBLOCKS));
|
||||
|
||||
xfs_icsb_lock_all_counters(mp);
|
||||
for_each_online_cpu(i) {
|
||||
cntp = per_cpu_ptr(mp->m_sb_cnts, i);
|
||||
switch (field) {
|
||||
case XFS_SBS_ICOUNT:
|
||||
cntp->icsb_icount = count + resid;
|
||||
break;
|
||||
case XFS_SBS_IFREE:
|
||||
cntp->icsb_ifree = count + resid;
|
||||
break;
|
||||
case XFS_SBS_FDBLOCKS:
|
||||
cntp->icsb_fdblocks = count + resid;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
resid = 0;
|
||||
}
|
||||
clear_bit(field, &mp->m_icsb_counters);
|
||||
xfs_icsb_unlock_all_counters(mp);
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_icsb_sync_counters_int(
|
||||
xfs_mount_t *mp,
|
||||
int flags)
|
||||
{
|
||||
xfs_icsb_cnts_t cnt;
|
||||
int s;
|
||||
|
||||
/* Pass 1: lock all counters */
|
||||
if ((flags & XFS_ICSB_SB_LOCKED) == 0)
|
||||
s = XFS_SB_LOCK(mp);
|
||||
|
||||
xfs_icsb_count(mp, &cnt, flags);
|
||||
|
||||
/* Step 3: update mp->m_sb fields */
|
||||
if (!xfs_icsb_counter_disabled(mp, XFS_SBS_ICOUNT))
|
||||
mp->m_sb.sb_icount = cnt.icsb_icount;
|
||||
if (!xfs_icsb_counter_disabled(mp, XFS_SBS_IFREE))
|
||||
mp->m_sb.sb_ifree = cnt.icsb_ifree;
|
||||
if (!xfs_icsb_counter_disabled(mp, XFS_SBS_FDBLOCKS))
|
||||
mp->m_sb.sb_fdblocks = cnt.icsb_fdblocks;
|
||||
|
||||
if ((flags & XFS_ICSB_SB_LOCKED) == 0)
|
||||
XFS_SB_UNLOCK(mp, s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Accurate update of per-cpu counters to incore superblock
|
||||
*/
|
||||
STATIC void
|
||||
xfs_icsb_sync_counters(
|
||||
xfs_mount_t *mp)
|
||||
{
|
||||
xfs_icsb_sync_counters_int(mp, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* lazy addition used for things like df, background sb syncs, etc
|
||||
*/
|
||||
void
|
||||
xfs_icsb_sync_counters_lazy(
|
||||
xfs_mount_t *mp)
|
||||
{
|
||||
xfs_icsb_sync_counters_int(mp, XFS_ICSB_LAZY_COUNT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Balance and enable/disable counters as necessary.
|
||||
*
|
||||
* Thresholds for re-enabling counters are somewhat magic.
|
||||
* inode counts are chosen to be the same number as single
|
||||
* on disk allocation chunk per CPU, and free blocks is
|
||||
* something far enough zero that we aren't going thrash
|
||||
* when we get near ENOSPC.
|
||||
*/
|
||||
#define XFS_ICSB_INO_CNTR_REENABLE 64
|
||||
#define XFS_ICSB_FDBLK_CNTR_REENABLE 512
|
||||
STATIC void
|
||||
xfs_icsb_balance_counter(
|
||||
xfs_mount_t *mp,
|
||||
xfs_sb_field_t field,
|
||||
int flags)
|
||||
{
|
||||
uint64_t count, resid = 0;
|
||||
int weight = num_online_cpus();
|
||||
int s;
|
||||
|
||||
if (!(flags & XFS_ICSB_SB_LOCKED))
|
||||
s = XFS_SB_LOCK(mp);
|
||||
|
||||
/* disable counter and sync counter */
|
||||
xfs_icsb_disable_counter(mp, field);
|
||||
|
||||
/* update counters - first CPU gets residual*/
|
||||
switch (field) {
|
||||
case XFS_SBS_ICOUNT:
|
||||
count = mp->m_sb.sb_icount;
|
||||
resid = do_div(count, weight);
|
||||
if (count < XFS_ICSB_INO_CNTR_REENABLE)
|
||||
goto out;
|
||||
break;
|
||||
case XFS_SBS_IFREE:
|
||||
count = mp->m_sb.sb_ifree;
|
||||
resid = do_div(count, weight);
|
||||
if (count < XFS_ICSB_INO_CNTR_REENABLE)
|
||||
goto out;
|
||||
break;
|
||||
case XFS_SBS_FDBLOCKS:
|
||||
count = mp->m_sb.sb_fdblocks;
|
||||
resid = do_div(count, weight);
|
||||
if (count < XFS_ICSB_FDBLK_CNTR_REENABLE)
|
||||
goto out;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
|
||||
xfs_icsb_enable_counter(mp, field, count, resid);
|
||||
out:
|
||||
if (!(flags & XFS_ICSB_SB_LOCKED))
|
||||
XFS_SB_UNLOCK(mp, s);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_icsb_modify_counters_int(
|
||||
xfs_mount_t *mp,
|
||||
xfs_sb_field_t field,
|
||||
int delta,
|
||||
int rsvd,
|
||||
int flags)
|
||||
{
|
||||
xfs_icsb_cnts_t *icsbp;
|
||||
long long lcounter; /* long counter for 64 bit fields */
|
||||
int cpu, s, locked = 0;
|
||||
int ret = 0, balance_done = 0;
|
||||
|
||||
again:
|
||||
cpu = get_cpu();
|
||||
icsbp = (xfs_icsb_cnts_t *)per_cpu_ptr(mp->m_sb_cnts, cpu),
|
||||
xfs_icsb_lock_cntr(icsbp);
|
||||
if (unlikely(xfs_icsb_counter_disabled(mp, field)))
|
||||
goto slow_path;
|
||||
|
||||
switch (field) {
|
||||
case XFS_SBS_ICOUNT:
|
||||
lcounter = icsbp->icsb_icount;
|
||||
lcounter += delta;
|
||||
if (unlikely(lcounter < 0))
|
||||
goto slow_path;
|
||||
icsbp->icsb_icount = lcounter;
|
||||
break;
|
||||
|
||||
case XFS_SBS_IFREE:
|
||||
lcounter = icsbp->icsb_ifree;
|
||||
lcounter += delta;
|
||||
if (unlikely(lcounter < 0))
|
||||
goto slow_path;
|
||||
icsbp->icsb_ifree = lcounter;
|
||||
break;
|
||||
|
||||
case XFS_SBS_FDBLOCKS:
|
||||
BUG_ON((mp->m_resblks - mp->m_resblks_avail) != 0);
|
||||
|
||||
lcounter = icsbp->icsb_fdblocks;
|
||||
lcounter += delta;
|
||||
if (unlikely(lcounter < 0))
|
||||
goto slow_path;
|
||||
icsbp->icsb_fdblocks = lcounter;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
xfs_icsb_unlock_cntr(icsbp);
|
||||
put_cpu();
|
||||
if (locked)
|
||||
XFS_SB_UNLOCK(mp, s);
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The slow path needs to be run with the SBLOCK
|
||||
* held so that we prevent other threads from
|
||||
* attempting to run this path at the same time.
|
||||
* this provides exclusion for the balancing code,
|
||||
* and exclusive fallback if the balance does not
|
||||
* provide enough resources to continue in an unlocked
|
||||
* manner.
|
||||
*/
|
||||
slow_path:
|
||||
xfs_icsb_unlock_cntr(icsbp);
|
||||
put_cpu();
|
||||
|
||||
/* need to hold superblock incase we need
|
||||
* to disable a counter */
|
||||
if (!(flags & XFS_ICSB_SB_LOCKED)) {
|
||||
s = XFS_SB_LOCK(mp);
|
||||
locked = 1;
|
||||
flags |= XFS_ICSB_SB_LOCKED;
|
||||
}
|
||||
if (!balance_done) {
|
||||
xfs_icsb_balance_counter(mp, field, flags);
|
||||
balance_done = 1;
|
||||
goto again;
|
||||
} else {
|
||||
/*
|
||||
* we might not have enough on this local
|
||||
* cpu to allocate for a bulk request.
|
||||
* We need to drain this field from all CPUs
|
||||
* and disable the counter fastpath
|
||||
*/
|
||||
xfs_icsb_disable_counter(mp, field);
|
||||
}
|
||||
|
||||
ret = xfs_mod_incore_sb_unlocked(mp, field, delta, rsvd);
|
||||
|
||||
if (locked)
|
||||
XFS_SB_UNLOCK(mp, s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_icsb_modify_counters(
|
||||
xfs_mount_t *mp,
|
||||
xfs_sb_field_t field,
|
||||
int delta,
|
||||
int rsvd)
|
||||
{
|
||||
return xfs_icsb_modify_counters_int(mp, field, delta, rsvd, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when superblock is already locked
|
||||
*/
|
||||
STATIC int
|
||||
xfs_icsb_modify_counters_locked(
|
||||
xfs_mount_t *mp,
|
||||
xfs_sb_field_t field,
|
||||
int delta,
|
||||
int rsvd)
|
||||
{
|
||||
return xfs_icsb_modify_counters_int(mp, field, delta,
|
||||
rsvd, XFS_ICSB_SB_LOCKED);
|
||||
}
|
||||
#endif
|
||||
|
@ -267,6 +267,34 @@ typedef struct xfs_ioops {
|
||||
#define XFS_IODONE(vfsp) \
|
||||
(*(mp)->m_io_ops.xfs_iodone)(vfsp)
|
||||
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
|
||||
/*
|
||||
* Valid per-cpu incore superblock counters. Note that if you add new counters,
|
||||
* you may need to define new counter disabled bit field descriptors as there
|
||||
* are more possible fields in the superblock that can fit in a bitfield on a
|
||||
* 32 bit platform. The XFS_SBS_* values for the current current counters just
|
||||
* fit.
|
||||
*/
|
||||
typedef struct xfs_icsb_cnts {
|
||||
uint64_t icsb_fdblocks;
|
||||
uint64_t icsb_ifree;
|
||||
uint64_t icsb_icount;
|
||||
unsigned long icsb_flags;
|
||||
} xfs_icsb_cnts_t;
|
||||
|
||||
#define XFS_ICSB_FLAG_LOCK (1 << 0) /* counter lock bit */
|
||||
|
||||
#define XFS_ICSB_SB_LOCKED (1 << 0) /* sb already locked */
|
||||
#define XFS_ICSB_LAZY_COUNT (1 << 1) /* accuracy not needed */
|
||||
|
||||
extern int xfs_icsb_init_counters(struct xfs_mount *);
|
||||
extern void xfs_icsb_sync_counters_lazy(struct xfs_mount *);
|
||||
|
||||
#else
|
||||
#define xfs_icsb_init_counters(mp) (0)
|
||||
#define xfs_icsb_sync_counters_lazy(mp) do { } while (0)
|
||||
#endif
|
||||
|
||||
typedef struct xfs_mount {
|
||||
bhv_desc_t m_bhv; /* vfs xfs behavior */
|
||||
@ -372,6 +400,11 @@ typedef struct xfs_mount {
|
||||
struct xfs_qmops m_qm_ops; /* vector of XQM ops */
|
||||
struct xfs_ioops m_io_ops; /* vector of I/O ops */
|
||||
atomic_t m_active_trans; /* number trans frozen */
|
||||
#ifdef HAVE_PERCPU_SB
|
||||
xfs_icsb_cnts_t *m_sb_cnts; /* per-cpu superblock counters */
|
||||
unsigned long m_icsb_counters; /* disabled per-cpu counters */
|
||||
struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */
|
||||
#endif
|
||||
} xfs_mount_t;
|
||||
|
||||
/*
|
||||
@ -386,8 +419,6 @@ typedef struct xfs_mount {
|
||||
#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem
|
||||
operations, typically for
|
||||
disk errors in metadata */
|
||||
#define XFS_MOUNT_NOATIME (1ULL << 5) /* don't modify inode access
|
||||
times on reads */
|
||||
#define XFS_MOUNT_RETERR (1ULL << 6) /* return alignment errors to
|
||||
user */
|
||||
#define XFS_MOUNT_NOALIGN (1ULL << 7) /* turn off stripe alignment
|
||||
@ -411,6 +442,8 @@ typedef struct xfs_mount {
|
||||
#define XFS_MOUNT_DIRSYNC (1ULL << 21) /* synchronous directory ops */
|
||||
#define XFS_MOUNT_COMPAT_IOSIZE (1ULL << 22) /* don't report large preferred
|
||||
* I/O size in stat() */
|
||||
#define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock
|
||||
counters */
|
||||
|
||||
|
||||
/*
|
||||
@ -472,11 +505,6 @@ xfs_preferred_iosize(xfs_mount_t *mp)
|
||||
#define XFS_CORRUPT_INCORE 0x8 /* Corrupt in-memory data structures */
|
||||
#define XFS_SHUTDOWN_REMOTE_REQ 0x10 /* Shutdown came from remote cell */
|
||||
|
||||
/*
|
||||
* xflags for xfs_syncsub
|
||||
*/
|
||||
#define XFS_XSYNC_RELOC 0x01
|
||||
|
||||
/*
|
||||
* Flags for xfs_mountfs
|
||||
*/
|
||||
@ -548,6 +576,8 @@ extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *);
|
||||
extern int xfs_unmountfs_writesb(xfs_mount_t *);
|
||||
extern int xfs_unmount_flush(xfs_mount_t *, int);
|
||||
extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int, int);
|
||||
extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t,
|
||||
int, int);
|
||||
extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
|
||||
uint, int);
|
||||
extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
|
||||
|
@ -89,6 +89,7 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
|
||||
*/
|
||||
extern int xfs_rwlock(bhv_desc_t *bdp, vrwlock_t write_lock);
|
||||
extern void xfs_rwunlock(bhv_desc_t *bdp, vrwlock_t write_lock);
|
||||
extern int xfs_setattr(bhv_desc_t *bdp, vattr_t *vap, int flags, cred_t *credp);
|
||||
extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf,
|
||||
xfs_off_t offset, cred_t *credp, int flags);
|
||||
extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state,
|
||||
|
@ -55,9 +55,140 @@ STATIC void xfs_trans_committed(xfs_trans_t *, int);
|
||||
STATIC void xfs_trans_chunk_committed(xfs_log_item_chunk_t *, xfs_lsn_t, int);
|
||||
STATIC void xfs_trans_free(xfs_trans_t *);
|
||||
|
||||
kmem_zone_t *xfs_trans_zone;
|
||||
kmem_zone_t *xfs_trans_zone;
|
||||
|
||||
|
||||
/*
|
||||
* Reservation functions here avoid a huge stack in xfs_trans_init
|
||||
* due to register overflow from temporaries in the calculations.
|
||||
*/
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_write_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_itruncate_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_rename_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_link_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_LINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_remove_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_symlink_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_create_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_mkdir_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_ifree_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_ichange_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_growdata_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_GROWDATA_LOG_RES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_growrtalloc_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_GROWRTALLOC_LOG_RES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_growrtzero_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_GROWRTZERO_LOG_RES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_growrtfree_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_GROWRTFREE_LOG_RES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_swrite_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_SWRITE_LOG_RES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_writeid_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_WRITEID_LOG_RES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_addafork_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_attrinval_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_ATTRINVAL_LOG_RES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_attrset_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_attrrm_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);
|
||||
}
|
||||
|
||||
STATIC uint
|
||||
xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp)
|
||||
{
|
||||
return XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the precomputed transaction reservation values
|
||||
* in the mount structure.
|
||||
@ -69,39 +200,27 @@ xfs_trans_init(
|
||||
xfs_trans_reservations_t *resp;
|
||||
|
||||
resp = &(mp->m_reservations);
|
||||
resp->tr_write =
|
||||
(uint)(XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_itruncate =
|
||||
(uint)(XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_rename =
|
||||
(uint)(XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_link = (uint)XFS_CALC_LINK_LOG_RES(mp);
|
||||
resp->tr_remove =
|
||||
(uint)(XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_symlink =
|
||||
(uint)(XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_create =
|
||||
(uint)(XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_mkdir =
|
||||
(uint)(XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_ifree =
|
||||
(uint)(XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_ichange =
|
||||
(uint)(XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_growdata = (uint)XFS_CALC_GROWDATA_LOG_RES(mp);
|
||||
resp->tr_swrite = (uint)XFS_CALC_SWRITE_LOG_RES(mp);
|
||||
resp->tr_writeid = (uint)XFS_CALC_WRITEID_LOG_RES(mp);
|
||||
resp->tr_addafork =
|
||||
(uint)(XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_attrinval = (uint)XFS_CALC_ATTRINVAL_LOG_RES(mp);
|
||||
resp->tr_attrset =
|
||||
(uint)(XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_attrrm =
|
||||
(uint)(XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp));
|
||||
resp->tr_clearagi = (uint)XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp);
|
||||
resp->tr_growrtalloc = (uint)XFS_CALC_GROWRTALLOC_LOG_RES(mp);
|
||||
resp->tr_growrtzero = (uint)XFS_CALC_GROWRTZERO_LOG_RES(mp);
|
||||
resp->tr_growrtfree = (uint)XFS_CALC_GROWRTFREE_LOG_RES(mp);
|
||||
resp->tr_write = xfs_calc_write_reservation(mp);
|
||||
resp->tr_itruncate = xfs_calc_itruncate_reservation(mp);
|
||||
resp->tr_rename = xfs_calc_rename_reservation(mp);
|
||||
resp->tr_link = xfs_calc_link_reservation(mp);
|
||||
resp->tr_remove = xfs_calc_remove_reservation(mp);
|
||||
resp->tr_symlink = xfs_calc_symlink_reservation(mp);
|
||||
resp->tr_create = xfs_calc_create_reservation(mp);
|
||||
resp->tr_mkdir = xfs_calc_mkdir_reservation(mp);
|
||||
resp->tr_ifree = xfs_calc_ifree_reservation(mp);
|
||||
resp->tr_ichange = xfs_calc_ichange_reservation(mp);
|
||||
resp->tr_growdata = xfs_calc_growdata_reservation(mp);
|
||||
resp->tr_swrite = xfs_calc_swrite_reservation(mp);
|
||||
resp->tr_writeid = xfs_calc_writeid_reservation(mp);
|
||||
resp->tr_addafork = xfs_calc_addafork_reservation(mp);
|
||||
resp->tr_attrinval = xfs_calc_attrinval_reservation(mp);
|
||||
resp->tr_attrset = xfs_calc_attrset_reservation(mp);
|
||||
resp->tr_attrrm = xfs_calc_attrrm_reservation(mp);
|
||||
resp->tr_clearagi = xfs_calc_clear_agi_bucket_reservation(mp);
|
||||
resp->tr_growrtalloc = xfs_calc_growrtalloc_reservation(mp);
|
||||
resp->tr_growrtzero = xfs_calc_growrtzero_reservation(mp);
|
||||
resp->tr_growrtfree = xfs_calc_growrtfree_reservation(mp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -380,7 +380,7 @@ typedef struct xfs_trans {
|
||||
xfs_trans_header_t t_header; /* header for in-log trans */
|
||||
unsigned int t_busy_free; /* busy descs free */
|
||||
xfs_log_busy_chunk_t t_busy; /* busy/async free blocks */
|
||||
xfs_pflags_t t_pflags; /* saved pflags state */
|
||||
unsigned long t_pflags; /* saved process flags state */
|
||||
} xfs_trans_t;
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -55,7 +55,7 @@
|
||||
#include "xfs_clnt.h"
|
||||
#include "xfs_fsops.h"
|
||||
|
||||
STATIC int xfs_sync(bhv_desc_t *, int, cred_t *);
|
||||
STATIC int xfs_sync(bhv_desc_t *, int, cred_t *);
|
||||
|
||||
int
|
||||
xfs_init(void)
|
||||
@ -77,11 +77,12 @@ xfs_init(void)
|
||||
"xfs_bmap_free_item");
|
||||
xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t),
|
||||
"xfs_btree_cur");
|
||||
xfs_inode_zone = kmem_zone_init(sizeof(xfs_inode_t), "xfs_inode");
|
||||
xfs_trans_zone = kmem_zone_init(sizeof(xfs_trans_t), "xfs_trans");
|
||||
xfs_da_state_zone =
|
||||
kmem_zone_init(sizeof(xfs_da_state_t), "xfs_da_state");
|
||||
xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf");
|
||||
xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork");
|
||||
xfs_acl_zone_init(xfs_acl_zone, "xfs_acl");
|
||||
|
||||
/*
|
||||
* The size of the zone allocated buf log item is the maximum
|
||||
@ -93,17 +94,30 @@ xfs_init(void)
|
||||
(((XFS_MAX_BLOCKSIZE / XFS_BLI_CHUNK) /
|
||||
NBWORD) * sizeof(int))),
|
||||
"xfs_buf_item");
|
||||
xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) +
|
||||
((XFS_EFD_MAX_FAST_EXTENTS - 1) * sizeof(xfs_extent_t))),
|
||||
xfs_efd_zone =
|
||||
kmem_zone_init((sizeof(xfs_efd_log_item_t) +
|
||||
((XFS_EFD_MAX_FAST_EXTENTS - 1) *
|
||||
sizeof(xfs_extent_t))),
|
||||
"xfs_efd_item");
|
||||
xfs_efi_zone = kmem_zone_init((sizeof(xfs_efi_log_item_t) +
|
||||
((XFS_EFI_MAX_FAST_EXTENTS - 1) * sizeof(xfs_extent_t))),
|
||||
xfs_efi_zone =
|
||||
kmem_zone_init((sizeof(xfs_efi_log_item_t) +
|
||||
((XFS_EFI_MAX_FAST_EXTENTS - 1) *
|
||||
sizeof(xfs_extent_t))),
|
||||
"xfs_efi_item");
|
||||
xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork");
|
||||
xfs_ili_zone = kmem_zone_init(sizeof(xfs_inode_log_item_t), "xfs_ili");
|
||||
xfs_chashlist_zone = kmem_zone_init(sizeof(xfs_chashlist_t),
|
||||
"xfs_chashlist");
|
||||
xfs_acl_zone_init(xfs_acl_zone, "xfs_acl");
|
||||
|
||||
/*
|
||||
* These zones warrant special memory allocator hints
|
||||
*/
|
||||
xfs_inode_zone =
|
||||
kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode",
|
||||
KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
|
||||
KM_ZONE_SPREAD, NULL);
|
||||
xfs_ili_zone =
|
||||
kmem_zone_init_flags(sizeof(xfs_inode_log_item_t), "xfs_ili",
|
||||
KM_ZONE_SPREAD, NULL);
|
||||
xfs_chashlist_zone =
|
||||
kmem_zone_init_flags(sizeof(xfs_chashlist_t), "xfs_chashlist",
|
||||
KM_ZONE_SPREAD, NULL);
|
||||
|
||||
/*
|
||||
* Allocate global trace buffers.
|
||||
@ -176,18 +190,18 @@ xfs_cleanup(void)
|
||||
ktrace_free(xfs_alloc_trace_buf);
|
||||
#endif
|
||||
|
||||
kmem_cache_destroy(xfs_bmap_free_item_zone);
|
||||
kmem_cache_destroy(xfs_btree_cur_zone);
|
||||
kmem_cache_destroy(xfs_inode_zone);
|
||||
kmem_cache_destroy(xfs_trans_zone);
|
||||
kmem_cache_destroy(xfs_da_state_zone);
|
||||
kmem_cache_destroy(xfs_dabuf_zone);
|
||||
kmem_cache_destroy(xfs_buf_item_zone);
|
||||
kmem_cache_destroy(xfs_efd_zone);
|
||||
kmem_cache_destroy(xfs_efi_zone);
|
||||
kmem_cache_destroy(xfs_ifork_zone);
|
||||
kmem_cache_destroy(xfs_ili_zone);
|
||||
kmem_cache_destroy(xfs_chashlist_zone);
|
||||
kmem_zone_destroy(xfs_bmap_free_item_zone);
|
||||
kmem_zone_destroy(xfs_btree_cur_zone);
|
||||
kmem_zone_destroy(xfs_inode_zone);
|
||||
kmem_zone_destroy(xfs_trans_zone);
|
||||
kmem_zone_destroy(xfs_da_state_zone);
|
||||
kmem_zone_destroy(xfs_dabuf_zone);
|
||||
kmem_zone_destroy(xfs_buf_item_zone);
|
||||
kmem_zone_destroy(xfs_efd_zone);
|
||||
kmem_zone_destroy(xfs_efi_zone);
|
||||
kmem_zone_destroy(xfs_ifork_zone);
|
||||
kmem_zone_destroy(xfs_ili_zone);
|
||||
kmem_zone_destroy(xfs_chashlist_zone);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -258,8 +272,6 @@ xfs_start_flags(
|
||||
mp->m_inoadd = XFS_INO64_OFFSET;
|
||||
}
|
||||
#endif
|
||||
if (ap->flags & XFSMNT_NOATIME)
|
||||
mp->m_flags |= XFS_MOUNT_NOATIME;
|
||||
if (ap->flags & XFSMNT_RETERR)
|
||||
mp->m_flags |= XFS_MOUNT_RETERR;
|
||||
if (ap->flags & XFSMNT_NOALIGN)
|
||||
@ -620,7 +632,7 @@ xfs_quiesce_fs(
|
||||
xfs_mount_t *mp)
|
||||
{
|
||||
int count = 0, pincount;
|
||||
|
||||
|
||||
xfs_refcache_purge_mp(mp);
|
||||
xfs_flush_buftarg(mp->m_ddev_targp, 0);
|
||||
xfs_finish_reclaim_all(mp, 0);
|
||||
@ -631,7 +643,7 @@ xfs_quiesce_fs(
|
||||
* meta data (typically directory updates).
|
||||
* Which then must be flushed and logged before
|
||||
* we can write the unmount record.
|
||||
*/
|
||||
*/
|
||||
do {
|
||||
xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, 0, NULL);
|
||||
pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
|
||||
@ -654,11 +666,6 @@ xfs_mntupdate(
|
||||
xfs_mount_t *mp = XFS_BHVTOM(bdp);
|
||||
int error;
|
||||
|
||||
if (args->flags & XFSMNT_NOATIME)
|
||||
mp->m_flags |= XFS_MOUNT_NOATIME;
|
||||
else
|
||||
mp->m_flags &= ~XFS_MOUNT_NOATIME;
|
||||
|
||||
if (args->flags & XFSMNT_BARRIER)
|
||||
mp->m_flags |= XFS_MOUNT_BARRIER;
|
||||
else
|
||||
@ -814,6 +821,7 @@ xfs_statvfs(
|
||||
|
||||
statp->f_type = XFS_SB_MAGIC;
|
||||
|
||||
xfs_icsb_sync_counters_lazy(mp);
|
||||
s = XFS_SB_LOCK(mp);
|
||||
statp->f_bsize = sbp->sb_blocksize;
|
||||
lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0;
|
||||
@ -1221,7 +1229,7 @@ xfs_sync_inodes(
|
||||
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
||||
|
||||
error = xfs_itobp(mp, NULL, ip,
|
||||
&dip, &bp, 0);
|
||||
&dip, &bp, 0, 0);
|
||||
if (!error) {
|
||||
xfs_buf_relse(bp);
|
||||
} else {
|
||||
@ -1690,10 +1698,7 @@ xfs_parseargs(
|
||||
int iosize;
|
||||
|
||||
args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
|
||||
|
||||
#if 0 /* XXX: off by default, until some remaining issues ironed out */
|
||||
args->flags |= XFSMNT_IDELETE; /* default to on */
|
||||
#endif
|
||||
args->flags |= XFSMNT_IDELETE;
|
||||
|
||||
if (!options)
|
||||
goto done;
|
||||
@ -1903,7 +1908,6 @@ xfs_showargs(
|
||||
{ XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
|
||||
{ XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
|
||||
{ XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
|
||||
{ XFS_MOUNT_IDELETE, "," MNTOPT_NOIKEEP },
|
||||
{ 0, NULL }
|
||||
};
|
||||
struct proc_xfs_info *xfs_infop;
|
||||
@ -1939,6 +1943,8 @@ xfs_showargs(
|
||||
seq_printf(m, "," MNTOPT_SWIDTH "=%d",
|
||||
(int)XFS_FSB_TO_BB(mp, mp->m_swidth));
|
||||
|
||||
if (!(mp->m_flags & XFS_MOUNT_IDELETE))
|
||||
seq_printf(m, "," MNTOPT_IKEEP);
|
||||
if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
|
||||
seq_printf(m, "," MNTOPT_LARGEIO);
|
||||
if (mp->m_flags & XFS_MOUNT_BARRIER)
|
||||
|
@ -615,6 +615,7 @@ xfs_setattr(
|
||||
code = xfs_igrow_start(ip, vap->va_size, credp);
|
||||
}
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
vn_iowait(vp); /* wait for the completion of any pending DIOs */
|
||||
if (!code)
|
||||
code = xfs_itruncate_data(ip, vap->va_size);
|
||||
if (code) {
|
||||
@ -1556,7 +1557,7 @@ xfs_release(
|
||||
if ((error = xfs_inactive_free_eofblocks(mp, ip)))
|
||||
return error;
|
||||
/* Update linux inode block count after free above */
|
||||
LINVFS_GET_IP(vp)->i_blocks = XFS_FSB_TO_BB(mp,
|
||||
vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp,
|
||||
ip->i_d.di_nblocks + ip->i_delayed_blks);
|
||||
}
|
||||
}
|
||||
@ -1637,7 +1638,7 @@ xfs_inactive(
|
||||
if ((error = xfs_inactive_free_eofblocks(mp, ip)))
|
||||
return VN_INACTIVE_CACHE;
|
||||
/* Update linux inode block count after free above */
|
||||
LINVFS_GET_IP(vp)->i_blocks = XFS_FSB_TO_BB(mp,
|
||||
vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp,
|
||||
ip->i_d.di_nblocks + ip->i_delayed_blks);
|
||||
}
|
||||
goto out;
|
||||
@ -3186,7 +3187,7 @@ xfs_rmdir(
|
||||
|
||||
/* Fall through to std_return with error = 0 or the errno
|
||||
* from xfs_trans_commit. */
|
||||
std_return:
|
||||
std_return:
|
||||
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_POSTREMOVE)) {
|
||||
(void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE,
|
||||
dir_vp, DM_RIGHT_NULL,
|
||||
@ -3196,12 +3197,12 @@ std_return:
|
||||
}
|
||||
return error;
|
||||
|
||||
error1:
|
||||
error1:
|
||||
xfs_bmap_cancel(&free_list);
|
||||
cancel_flags |= XFS_TRANS_ABORT;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
error_return:
|
||||
error_return:
|
||||
xfs_trans_cancel(tp, cancel_flags);
|
||||
goto std_return;
|
||||
}
|
||||
@ -4310,8 +4311,10 @@ xfs_free_file_space(
|
||||
ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1);
|
||||
if (attr_flags & ATTR_NOLOCK)
|
||||
need_iolock = 0;
|
||||
if (need_iolock)
|
||||
if (need_iolock) {
|
||||
xfs_ilock(ip, XFS_IOLOCK_EXCL);
|
||||
vn_iowait(vp); /* wait for the completion of any pending DIOs */
|
||||
}
|
||||
|
||||
rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
|
||||
(__uint8_t)NBPP);
|
||||
|
Loading…
x
Reference in New Issue
Block a user