forked from Minki/linux
Merge git://oss.sgi.com:8090/xfs/xfs-2.6
* git://oss.sgi.com:8090/xfs/xfs-2.6: (49 commits) [XFS] Remove v1 dir trace macro - missed in a past commit. [XFS] 955947: Infinite loop in xfs_bulkstat() on formatter() error [XFS] pv 956241, author: nathans, rv: vapo - make ino validation checks [XFS] pv 956240, author: nathans, rv: vapo - Minor fixes in [XFS] Really fix use after free in xfs_iunpin. [XFS] Collapse sv_init and init_sv into just the one interface. [XFS] standardize on one sema init macro [XFS] Reduce endian flipping in alloc_btree, same as was done for [XFS] Minor cleanup from dio locking fix, remove an extra conditional. [XFS] Fix kmem_zalloc_greedy warnings on 64 bit platforms. [XFS] pv 955157, rv bnaujok - break the loop on EFAULT formatter() error [XFS] pv 955157, rv bnaujok - break the loop on formatter() error [XFS] Fixes the leak in reservation space because we weren't ungranting [XFS] Add lock annotations to xfs_trans_update_ail and [XFS] Fix a porting botch on the realtime subvol growfs code path. [XFS] Minor code rearranging and cleanup to prevent some coverity false [XFS] Remove a no-longer-correct debug assert from dio completion [XFS] Add a greedy allocation interface, allocating within a min/max size [XFS] Improve error handling for the zero-fsblock extent detection code. [XFS] Be more defensive with page flags (error/private) for metadata ...
This commit is contained in:
commit
c0341b0f47
@ -30,7 +30,6 @@ ifeq ($(CONFIG_XFS_TRACE),y)
|
||||
EXTRA_CFLAGS += -DXFS_BLI_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_BMAP_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_BMBT_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_DIR_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_DIR2_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_DQUOT_TRACE
|
||||
EXTRA_CFLAGS += -DXFS_ILOCK_TRACE
|
||||
|
@ -34,6 +34,14 @@ kmem_alloc(size_t size, unsigned int __nocast flags)
|
||||
gfp_t lflags = kmem_flags_convert(flags);
|
||||
void *ptr;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (unlikely(!(flags & KM_LARGE) && (size > PAGE_SIZE))) {
|
||||
printk(KERN_WARNING "Large %s attempt, size=%ld\n",
|
||||
__FUNCTION__, (long)size);
|
||||
dump_stack();
|
||||
}
|
||||
#endif
|
||||
|
||||
do {
|
||||
if (size < MAX_SLAB_SIZE || retries > MAX_VMALLOCS)
|
||||
ptr = kmalloc(size, lflags);
|
||||
@ -60,6 +68,27 @@ kmem_zalloc(size_t size, unsigned int __nocast flags)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
kmem_zalloc_greedy(size_t *size, size_t minsize, size_t maxsize,
|
||||
unsigned int __nocast flags)
|
||||
{
|
||||
void *ptr;
|
||||
size_t kmsize = maxsize;
|
||||
unsigned int kmflags = (flags & ~KM_SLEEP) | KM_NOSLEEP;
|
||||
|
||||
while (!(ptr = kmem_zalloc(kmsize, kmflags))) {
|
||||
if ((kmsize <= minsize) && (flags & KM_NOSLEEP))
|
||||
break;
|
||||
if ((kmsize >>= 1) <= minsize) {
|
||||
kmsize = minsize;
|
||||
kmflags = flags;
|
||||
}
|
||||
}
|
||||
if (ptr)
|
||||
*size = kmsize;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
kmem_free(void *ptr, size_t size)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define KM_NOSLEEP 0x0002u
|
||||
#define KM_NOFS 0x0004u
|
||||
#define KM_MAYFAIL 0x0008u
|
||||
#define KM_LARGE 0x0010u
|
||||
|
||||
/*
|
||||
* We use a special process flag to avoid recursive callbacks into
|
||||
@ -41,7 +42,7 @@ kmem_flags_convert(unsigned int __nocast flags)
|
||||
{
|
||||
gfp_t lflags;
|
||||
|
||||
BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL));
|
||||
BUG_ON(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS|KM_MAYFAIL|KM_LARGE));
|
||||
|
||||
if (flags & KM_NOSLEEP) {
|
||||
lflags = GFP_ATOMIC | __GFP_NOWARN;
|
||||
@ -54,8 +55,9 @@ kmem_flags_convert(unsigned int __nocast flags)
|
||||
}
|
||||
|
||||
extern void *kmem_alloc(size_t, unsigned int __nocast);
|
||||
extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
|
||||
extern void *kmem_zalloc(size_t, unsigned int __nocast);
|
||||
extern void *kmem_zalloc_greedy(size_t *, size_t, size_t, unsigned int __nocast);
|
||||
extern void *kmem_realloc(void *, size_t, size_t, unsigned int __nocast);
|
||||
extern void kmem_free(void *, size_t);
|
||||
|
||||
/*
|
||||
|
@ -29,8 +29,6 @@
|
||||
|
||||
typedef struct semaphore sema_t;
|
||||
|
||||
#define init_sema(sp, val, c, d) sema_init(sp, val)
|
||||
#define initsema(sp, val) sema_init(sp, val)
|
||||
#define initnsema(sp, val, name) sema_init(sp, val)
|
||||
#define psema(sp, b) down(sp)
|
||||
#define vsema(sp) up(sp)
|
||||
|
@ -53,8 +53,6 @@ static inline void _sv_wait(sv_t *sv, spinlock_t *lock, int state,
|
||||
remove_wait_queue(&sv->waiters, &wait);
|
||||
}
|
||||
|
||||
#define init_sv(sv,type,name,flag) \
|
||||
init_waitqueue_head(&(sv)->waiters)
|
||||
#define sv_init(sv,flag,name) \
|
||||
init_waitqueue_head(&(sv)->waiters)
|
||||
#define sv_destroy(sv) \
|
||||
|
@ -71,7 +71,7 @@ xfs_page_trace(
|
||||
int tag,
|
||||
struct inode *inode,
|
||||
struct page *page,
|
||||
int mask)
|
||||
unsigned long pgoff)
|
||||
{
|
||||
xfs_inode_t *ip;
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
@ -91,7 +91,7 @@ xfs_page_trace(
|
||||
(void *)ip,
|
||||
(void *)inode,
|
||||
(void *)page,
|
||||
(void *)((unsigned long)mask),
|
||||
(void *)pgoff,
|
||||
(void *)((unsigned long)((ip->i_d.di_size >> 32) & 0xffffffff)),
|
||||
(void *)((unsigned long)(ip->i_d.di_size & 0xffffffff)),
|
||||
(void *)((unsigned long)((isize >> 32) & 0xffffffff)),
|
||||
@ -105,7 +105,7 @@ xfs_page_trace(
|
||||
(void *)NULL);
|
||||
}
|
||||
#else
|
||||
#define xfs_page_trace(tag, inode, page, mask)
|
||||
#define xfs_page_trace(tag, inode, page, pgoff)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -1197,7 +1197,7 @@ xfs_vm_releasepage(
|
||||
.nr_to_write = 1,
|
||||
};
|
||||
|
||||
xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, gfp_mask);
|
||||
xfs_page_trace(XFS_RELEASEPAGE_ENTER, inode, page, 0);
|
||||
|
||||
if (!page_has_buffers(page))
|
||||
return 0;
|
||||
@ -1356,7 +1356,6 @@ xfs_end_io_direct(
|
||||
ioend->io_size = size;
|
||||
xfs_finish_ioend(ioend);
|
||||
} else {
|
||||
ASSERT(size >= 0);
|
||||
xfs_destroy_ioend(ioend);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2005 Silicon Graphics, Inc.
|
||||
* Copyright (c) 2000-2006 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@ -318,8 +318,12 @@ xfs_buf_free(
|
||||
if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1))
|
||||
free_address(bp->b_addr - bp->b_offset);
|
||||
|
||||
for (i = 0; i < bp->b_page_count; i++)
|
||||
page_cache_release(bp->b_pages[i]);
|
||||
for (i = 0; i < bp->b_page_count; i++) {
|
||||
struct page *page = bp->b_pages[i];
|
||||
|
||||
ASSERT(!PagePrivate(page));
|
||||
page_cache_release(page);
|
||||
}
|
||||
_xfs_buf_free_pages(bp);
|
||||
} else if (bp->b_flags & _XBF_KMEM_ALLOC) {
|
||||
/*
|
||||
@ -400,6 +404,7 @@ _xfs_buf_lookup_pages(
|
||||
nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset);
|
||||
size -= nbytes;
|
||||
|
||||
ASSERT(!PagePrivate(page));
|
||||
if (!PageUptodate(page)) {
|
||||
page_count--;
|
||||
if (blocksize >= PAGE_CACHE_SIZE) {
|
||||
@ -768,7 +773,7 @@ xfs_buf_get_noaddr(
|
||||
_xfs_buf_initialize(bp, target, 0, len, 0);
|
||||
|
||||
try_again:
|
||||
data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL);
|
||||
data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE);
|
||||
if (unlikely(data == NULL))
|
||||
goto fail_free_buf;
|
||||
|
||||
@ -1117,10 +1122,10 @@ xfs_buf_bio_end_io(
|
||||
do {
|
||||
struct page *page = bvec->bv_page;
|
||||
|
||||
ASSERT(!PagePrivate(page));
|
||||
if (unlikely(bp->b_error)) {
|
||||
if (bp->b_flags & XBF_READ)
|
||||
ClearPageUptodate(page);
|
||||
SetPageError(page);
|
||||
} else if (blocksize >= PAGE_CACHE_SIZE) {
|
||||
SetPageUptodate(page);
|
||||
} else if (!PagePrivate(page) &&
|
||||
@ -1156,16 +1161,16 @@ _xfs_buf_ioapply(
|
||||
total_nr_pages = bp->b_page_count;
|
||||
map_i = 0;
|
||||
|
||||
if (bp->b_flags & _XBF_RUN_QUEUES) {
|
||||
bp->b_flags &= ~_XBF_RUN_QUEUES;
|
||||
rw = (bp->b_flags & XBF_READ) ? READ_SYNC : WRITE_SYNC;
|
||||
} else {
|
||||
rw = (bp->b_flags & XBF_READ) ? READ : WRITE;
|
||||
}
|
||||
|
||||
if (bp->b_flags & XBF_ORDERED) {
|
||||
ASSERT(!(bp->b_flags & XBF_READ));
|
||||
rw = WRITE_BARRIER;
|
||||
} else if (bp->b_flags & _XBF_RUN_QUEUES) {
|
||||
ASSERT(!(bp->b_flags & XBF_READ_AHEAD));
|
||||
bp->b_flags &= ~_XBF_RUN_QUEUES;
|
||||
rw = (bp->b_flags & XBF_WRITE) ? WRITE_SYNC : READ_SYNC;
|
||||
} else {
|
||||
rw = (bp->b_flags & XBF_WRITE) ? WRITE :
|
||||
(bp->b_flags & XBF_READ_AHEAD) ? READA : READ;
|
||||
}
|
||||
|
||||
/* Special code path for reading a sub page size buffer in --
|
||||
@ -1681,6 +1686,7 @@ xfsbufd(
|
||||
xfs_buf_t *bp, *n;
|
||||
struct list_head *dwq = &target->bt_delwrite_queue;
|
||||
spinlock_t *dwlk = &target->bt_delwrite_lock;
|
||||
int count;
|
||||
|
||||
current->flags |= PF_MEMALLOC;
|
||||
|
||||
@ -1696,6 +1702,7 @@ xfsbufd(
|
||||
schedule_timeout_interruptible(
|
||||
xfs_buf_timer_centisecs * msecs_to_jiffies(10));
|
||||
|
||||
count = 0;
|
||||
age = xfs_buf_age_centisecs * msecs_to_jiffies(10);
|
||||
spin_lock(dwlk);
|
||||
list_for_each_entry_safe(bp, n, dwq, b_list) {
|
||||
@ -1711,9 +1718,11 @@ xfsbufd(
|
||||
break;
|
||||
}
|
||||
|
||||
bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);
|
||||
bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|
|
||||
_XBF_RUN_QUEUES);
|
||||
bp->b_flags |= XBF_WRITE;
|
||||
list_move(&bp->b_list, &tmp);
|
||||
list_move_tail(&bp->b_list, &tmp);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
spin_unlock(dwlk);
|
||||
@ -1724,12 +1733,12 @@ xfsbufd(
|
||||
|
||||
list_del_init(&bp->b_list);
|
||||
xfs_buf_iostrategy(bp);
|
||||
|
||||
blk_run_address_space(target->bt_mapping);
|
||||
}
|
||||
|
||||
if (as_list_len > 0)
|
||||
purge_addresses();
|
||||
if (count)
|
||||
blk_run_address_space(target->bt_mapping);
|
||||
|
||||
clear_bit(XBT_FORCE_FLUSH, &target->bt_flags);
|
||||
} while (!kthread_should_stop());
|
||||
@ -1767,7 +1776,7 @@ xfs_flush_buftarg(
|
||||
continue;
|
||||
}
|
||||
|
||||
list_move(&bp->b_list, &tmp);
|
||||
list_move_tail(&bp->b_list, &tmp);
|
||||
}
|
||||
spin_unlock(dwlk);
|
||||
|
||||
@ -1776,7 +1785,7 @@ xfs_flush_buftarg(
|
||||
*/
|
||||
list_for_each_entry_safe(bp, n, &tmp, b_list) {
|
||||
xfs_buf_lock(bp);
|
||||
bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q);
|
||||
bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|_XBF_RUN_QUEUES);
|
||||
bp->b_flags |= XBF_WRITE;
|
||||
if (wait)
|
||||
bp->b_flags &= ~XBF_ASYNC;
|
||||
@ -1786,6 +1795,9 @@ xfs_flush_buftarg(
|
||||
xfs_buf_iostrategy(bp);
|
||||
}
|
||||
|
||||
if (wait)
|
||||
blk_run_address_space(target->bt_mapping);
|
||||
|
||||
/*
|
||||
* Remaining list items must be flushed before returning
|
||||
*/
|
||||
@ -1797,9 +1809,6 @@ xfs_flush_buftarg(
|
||||
xfs_buf_relse(bp);
|
||||
}
|
||||
|
||||
if (wait)
|
||||
blk_run_address_space(target->bt_mapping);
|
||||
|
||||
return pincount;
|
||||
}
|
||||
|
||||
|
@ -298,11 +298,6 @@ extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *);
|
||||
#define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE)
|
||||
#define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE)
|
||||
|
||||
#define XFS_BUF_ISUNINITIAL(bp) (0)
|
||||
#define XFS_BUF_UNUNINITIAL(bp) (0)
|
||||
|
||||
#define XFS_BUF_BP_ISMAPPED(bp) (1)
|
||||
|
||||
#define XFS_BUF_IODONE_FUNC(bp) ((bp)->b_iodone)
|
||||
#define XFS_BUF_SET_IODONE_FUNC(bp, func) ((bp)->b_iodone = (func))
|
||||
#define XFS_BUF_CLR_IODONE_FUNC(bp) ((bp)->b_iodone = NULL)
|
||||
@ -393,8 +388,6 @@ static inline int XFS_bwrite(xfs_buf_t *bp)
|
||||
return error;
|
||||
}
|
||||
|
||||
#define XFS_bdwrite(bp) xfs_buf_iostart(bp, XBF_DELWRI | XBF_ASYNC)
|
||||
|
||||
static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)
|
||||
{
|
||||
bp->b_strat = xfs_bdstrat_cb;
|
||||
|
@ -34,7 +34,7 @@ xfs_param_t xfs_params = {
|
||||
.restrict_chown = { 0, 1, 1 },
|
||||
.sgid_inherit = { 0, 0, 1 },
|
||||
.symlink_mode = { 0, 0, 1 },
|
||||
.panic_mask = { 0, 0, 127 },
|
||||
.panic_mask = { 0, 0, 255 },
|
||||
.error_level = { 0, 3, 11 },
|
||||
.syncd_timer = { 1*100, 30*100, 7200*100},
|
||||
.stats_clear = { 0, 0, 1 },
|
||||
|
@ -653,7 +653,7 @@ xfs_attrmulti_by_handle(
|
||||
STATIC int
|
||||
xfs_ioc_space(
|
||||
bhv_desc_t *bdp,
|
||||
bhv_vnode_t *vp,
|
||||
struct inode *inode,
|
||||
struct file *filp,
|
||||
int flags,
|
||||
unsigned int cmd,
|
||||
@ -735,7 +735,7 @@ xfs_ioctl(
|
||||
!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
return xfs_ioc_space(bdp, vp, filp, ioflags, cmd, arg);
|
||||
return xfs_ioc_space(bdp, inode, filp, ioflags, cmd, arg);
|
||||
|
||||
case XFS_IOC_DIOINFO: {
|
||||
struct dioattr da;
|
||||
@ -763,6 +763,8 @@ xfs_ioctl(
|
||||
return xfs_ioc_fsgeometry(mp, arg);
|
||||
|
||||
case XFS_IOC_GETVERSION:
|
||||
return put_user(inode->i_generation, (int __user *)arg);
|
||||
|
||||
case XFS_IOC_GETXFLAGS:
|
||||
case XFS_IOC_SETXFLAGS:
|
||||
case XFS_IOC_FSGETXATTR:
|
||||
@ -957,7 +959,7 @@ xfs_ioctl(
|
||||
STATIC int
|
||||
xfs_ioc_space(
|
||||
bhv_desc_t *bdp,
|
||||
bhv_vnode_t *vp,
|
||||
struct inode *inode,
|
||||
struct file *filp,
|
||||
int ioflags,
|
||||
unsigned int cmd,
|
||||
@ -967,13 +969,13 @@ xfs_ioc_space(
|
||||
int attr_flags = 0;
|
||||
int error;
|
||||
|
||||
if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
|
||||
if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
|
||||
return -XFS_ERROR(EPERM);
|
||||
|
||||
if (!(filp->f_mode & FMODE_WRITE))
|
||||
return -XFS_ERROR(EBADF);
|
||||
|
||||
if (!VN_ISREG(vp))
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
return -XFS_ERROR(EINVAL);
|
||||
|
||||
if (copy_from_user(&bf, arg, sizeof(bf)))
|
||||
@ -1264,13 +1266,6 @@ xfs_ioc_xattr(
|
||||
break;
|
||||
}
|
||||
|
||||
case XFS_IOC_GETVERSION: {
|
||||
flags = vn_to_inode(vp)->i_generation;
|
||||
if (copy_to_user(arg, &flags, sizeof(flags)))
|
||||
error = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
error = -ENOTTY;
|
||||
break;
|
||||
|
@ -623,12 +623,27 @@ xfs_vn_getattr(
|
||||
{
|
||||
struct inode *inode = dentry->d_inode;
|
||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
||||
int error = 0;
|
||||
bhv_vattr_t vattr = { .va_mask = XFS_AT_STAT };
|
||||
int error;
|
||||
|
||||
if (unlikely(vp->v_flag & VMODIFIED))
|
||||
error = vn_revalidate(vp);
|
||||
if (!error)
|
||||
generic_fillattr(inode, stat);
|
||||
error = bhv_vop_getattr(vp, &vattr, ATTR_LAZY, NULL);
|
||||
if (likely(!error)) {
|
||||
stat->size = i_size_read(inode);
|
||||
stat->dev = inode->i_sb->s_dev;
|
||||
stat->rdev = (vattr.va_rdev == 0) ? 0 :
|
||||
MKDEV(sysv_major(vattr.va_rdev) & 0x1ff,
|
||||
sysv_minor(vattr.va_rdev));
|
||||
stat->mode = vattr.va_mode;
|
||||
stat->nlink = vattr.va_nlink;
|
||||
stat->uid = vattr.va_uid;
|
||||
stat->gid = vattr.va_gid;
|
||||
stat->ino = vattr.va_nodeid;
|
||||
stat->atime = vattr.va_atime;
|
||||
stat->mtime = vattr.va_mtime;
|
||||
stat->ctime = vattr.va_ctime;
|
||||
stat->blocks = vattr.va_nblocks;
|
||||
stat->blksize = vattr.va_blocksize;
|
||||
}
|
||||
return -error;
|
||||
}
|
||||
|
||||
|
@ -148,11 +148,7 @@ BUFFER_FNS(PrivateStart, unwritten);
|
||||
(current->flags = ((current->flags & ~(f)) | (*(sp) & (f))))
|
||||
|
||||
#define NBPP PAGE_SIZE
|
||||
#define DPPSHFT (PAGE_SHIFT - 9)
|
||||
#define NDPP (1 << (PAGE_SHIFT - 9))
|
||||
#define dtop(DD) (((DD) + NDPP - 1) >> DPPSHFT)
|
||||
#define dtopt(DD) ((DD) >> DPPSHFT)
|
||||
#define dpoff(DD) ((DD) & (NDPP-1))
|
||||
|
||||
#define NBBY 8 /* number of bits per byte */
|
||||
#define NBPC PAGE_SIZE /* Number of bytes per click */
|
||||
@ -172,8 +168,6 @@ BUFFER_FNS(PrivateStart, unwritten);
|
||||
#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT)
|
||||
#define btoc64(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
|
||||
#define btoct64(x) ((__uint64_t)(x)>>BPCSHIFT)
|
||||
#define io_btoc(x) (((__psunsigned_t)(x)+(IO_NBPC-1))>>IO_BPCSHIFT)
|
||||
#define io_btoct(x) ((__psunsigned_t)(x)>>IO_BPCSHIFT)
|
||||
|
||||
/* off_t bytes to clicks */
|
||||
#define offtoc(x) (((__uint64_t)(x)+(NBPC-1))>>BPCSHIFT)
|
||||
@ -186,7 +180,6 @@ BUFFER_FNS(PrivateStart, unwritten);
|
||||
#define ctob(x) ((__psunsigned_t)(x)<<BPCSHIFT)
|
||||
#define btoct(x) ((__psunsigned_t)(x)>>BPCSHIFT)
|
||||
#define ctob64(x) ((__uint64_t)(x)<<BPCSHIFT)
|
||||
#define io_ctob(x) ((__psunsigned_t)(x)<<IO_BPCSHIFT)
|
||||
|
||||
/* bytes to clicks */
|
||||
#define btoc(x) (((__psunsigned_t)(x)+(NBPC-1))>>BPCSHIFT)
|
||||
@ -339,4 +332,11 @@ static inline __uint64_t roundup_64(__uint64_t x, __uint32_t y)
|
||||
return(x * y);
|
||||
}
|
||||
|
||||
static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y)
|
||||
{
|
||||
x += y - 1;
|
||||
do_div(x, y);
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif /* __XFS_LINUX__ */
|
||||
|
@ -270,12 +270,12 @@ xfs_read(
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely((ioflags & IO_ISDIRECT) && VN_CACHED(vp)))
|
||||
bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
|
||||
-1, FI_REMAPF_LOCKED);
|
||||
|
||||
if (unlikely(ioflags & IO_ISDIRECT))
|
||||
if (unlikely(ioflags & IO_ISDIRECT)) {
|
||||
if (VN_CACHED(vp))
|
||||
bhv_vop_flushinval_pages(vp, ctooff(offtoct(*offset)),
|
||||
-1, FI_REMAPF_LOCKED);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
}
|
||||
|
||||
xfs_rw_enter_trace(XFS_READ_ENTER, &ip->i_iocore,
|
||||
(void *)iovp, segs, *offset, ioflags);
|
||||
|
@ -227,7 +227,9 @@ xfs_initialize_vnode(
|
||||
xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
|
||||
xfs_set_inodeops(inode);
|
||||
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
ip->i_flags &= ~XFS_INEW;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
barrier();
|
||||
|
||||
unlock_new_inode(inode);
|
||||
|
@ -79,7 +79,7 @@ typedef enum {
|
||||
#define VFS_RDONLY 0x0001 /* read-only vfs */
|
||||
#define VFS_GRPID 0x0002 /* group-ID assigned from directory */
|
||||
#define VFS_DMI 0x0004 /* filesystem has the DMI enabled */
|
||||
#define VFS_UMOUNT 0x0008 /* unmount in progress */
|
||||
/* ---- VFS_UMOUNT ---- 0x0008 -- unneeded, fixed via kthread APIs */
|
||||
#define VFS_32BITINODES 0x0010 /* do not use inums above 32 bits */
|
||||
#define VFS_END 0x0010 /* max flag */
|
||||
|
||||
|
@ -85,8 +85,6 @@ typedef enum {
|
||||
#define VN_BHV_HEAD(vp) ((bhv_head_t *)(&((vp)->v_bh)))
|
||||
#define vn_bhv_head_init(bhp,name) bhv_head_init(bhp,name)
|
||||
#define vn_bhv_remove(bhp,bdp) bhv_remove(bhp,bdp)
|
||||
#define vn_bhv_lookup(bhp,ops) bhv_lookup(bhp,ops)
|
||||
#define vn_bhv_lookup_unlocked(bhp,ops) bhv_lookup_unlocked(bhp,ops)
|
||||
|
||||
/*
|
||||
* Vnode to Linux inode mapping.
|
||||
|
@ -381,18 +381,6 @@ xfs_qm_dquot_logitem_unlock(
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The transaction with the dquot locked has aborted. The dquot
|
||||
* must not be dirty within the transaction. We simply unlock just
|
||||
* as if the transaction had been cancelled.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_qm_dquot_logitem_abort(
|
||||
xfs_dq_logitem_t *ql)
|
||||
{
|
||||
xfs_qm_dquot_logitem_unlock(ql);
|
||||
}
|
||||
|
||||
/*
|
||||
* this needs to stamp an lsn into the dquot, I think.
|
||||
* rpc's that look at user dquot's would then have to
|
||||
@ -426,7 +414,6 @@ STATIC struct xfs_item_ops xfs_dquot_item_ops = {
|
||||
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_qm_dquot_logitem_committed,
|
||||
.iop_push = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push,
|
||||
.iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_abort,
|
||||
.iop_pushbuf = (void(*)(xfs_log_item_t*))
|
||||
xfs_qm_dquot_logitem_pushbuf,
|
||||
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
@ -558,17 +545,6 @@ xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn)
|
||||
return (lsn);
|
||||
}
|
||||
|
||||
/*
|
||||
* The transaction of which this QUOTAOFF is a part has been aborted.
|
||||
* Just clean up after ourselves.
|
||||
* Shouldn't this never happen in the case of qoffend logitems? XXX
|
||||
*/
|
||||
STATIC void
|
||||
xfs_qm_qoff_logitem_abort(xfs_qoff_logitem_t *qf)
|
||||
{
|
||||
kmem_free(qf, sizeof(xfs_qoff_logitem_t));
|
||||
}
|
||||
|
||||
/*
|
||||
* There isn't much you can do to push on an quotaoff item. It is simply
|
||||
* stuck waiting for the log to be flushed to disk.
|
||||
@ -644,7 +620,6 @@ STATIC struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
|
||||
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_qm_qoffend_logitem_committed,
|
||||
.iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
|
||||
.iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort,
|
||||
.iop_pushbuf = NULL,
|
||||
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_qm_qoffend_logitem_committing
|
||||
@ -667,7 +642,6 @@ STATIC struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
|
||||
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_qm_qoff_logitem_committed,
|
||||
.iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
|
||||
.iop_abort = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_abort,
|
||||
.iop_pushbuf = NULL,
|
||||
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_qm_qoff_logitem_committing
|
||||
|
@ -112,17 +112,17 @@ xfs_Gqm_init(void)
|
||||
{
|
||||
xfs_dqhash_t *udqhash, *gdqhash;
|
||||
xfs_qm_t *xqm;
|
||||
uint i, hsize, flags = KM_SLEEP | KM_MAYFAIL;
|
||||
size_t hsize;
|
||||
uint i;
|
||||
|
||||
/*
|
||||
* Initialize the dquot hash tables.
|
||||
*/
|
||||
hsize = XFS_QM_HASHSIZE_HIGH;
|
||||
while (!(udqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), flags))) {
|
||||
if ((hsize >>= 1) <= XFS_QM_HASHSIZE_LOW)
|
||||
flags = KM_SLEEP;
|
||||
}
|
||||
gdqhash = kmem_zalloc(hsize * sizeof(xfs_dqhash_t), KM_SLEEP);
|
||||
udqhash = kmem_zalloc_greedy(&hsize,
|
||||
XFS_QM_HASHSIZE_LOW, XFS_QM_HASHSIZE_HIGH,
|
||||
KM_SLEEP | KM_MAYFAIL | KM_LARGE);
|
||||
gdqhash = kmem_zalloc(hsize, KM_SLEEP | KM_LARGE);
|
||||
hsize /= sizeof(xfs_dqhash_t);
|
||||
ndquot = hsize << 8;
|
||||
|
||||
xqm = kmem_zalloc(sizeof(xfs_qm_t), KM_SLEEP);
|
||||
|
@ -55,12 +55,6 @@ extern kmem_zone_t *qm_dqtrxzone;
|
||||
#define XFS_QM_HASHSIZE_LOW (NBPP / sizeof(xfs_dqhash_t))
|
||||
#define XFS_QM_HASHSIZE_HIGH ((NBPP * 4) / sizeof(xfs_dqhash_t))
|
||||
|
||||
/*
|
||||
* We output a cmn_err when quotachecking a quota file with more than
|
||||
* this many fsbs.
|
||||
*/
|
||||
#define XFS_QM_BIG_QCHECK_NBLKS 500
|
||||
|
||||
/*
|
||||
* This defines the unit of allocation of dquots.
|
||||
* Currently, it is just one file system block, and a 4K blk contains 30
|
||||
|
@ -75,7 +75,6 @@ static inline int XQMISLCKD(struct xfs_dqhash *h)
|
||||
|
||||
#define xfs_qm_freelist_lock(qm) XQMLCK(&((qm)->qm_dqfreelist))
|
||||
#define xfs_qm_freelist_unlock(qm) XQMUNLCK(&((qm)->qm_dqfreelist))
|
||||
#define XFS_QM_IS_FREELIST_LOCKED(qm) XQMISLCKD(&((qm)->qm_dqfreelist))
|
||||
|
||||
/*
|
||||
* Hash into a bucket in the dquot hash table, based on <mp, id>.
|
||||
@ -170,6 +169,5 @@ for ((dqp) = (qlist)->qh_next; (dqp) != (xfs_dquot_t *)(qlist); \
|
||||
#define DQFLAGTO_TYPESTR(d) (((d)->dq_flags & XFS_DQ_USER) ? "USR" : \
|
||||
(((d)->dq_flags & XFS_DQ_GROUP) ? "GRP" : \
|
||||
(((d)->dq_flags & XFS_DQ_PROJ) ? "PRJ":"???")))
|
||||
#define DQFLAGTO_DIRTYSTR(d) (XFS_DQ_IS_DIRTY(d) ? "DIRTY" : "NOTDIRTY")
|
||||
|
||||
#endif /* __XFS_QUOTA_PRIV_H__ */
|
||||
|
@ -75,7 +75,7 @@ ktrace_alloc(int nentries, unsigned int __nocast sleep)
|
||||
sleep);
|
||||
} else {
|
||||
ktep = (ktrace_entry_t*)kmem_zalloc((nentries * sizeof(*ktep)),
|
||||
sleep);
|
||||
sleep | KM_LARGE);
|
||||
}
|
||||
|
||||
if (ktep == NULL) {
|
||||
|
@ -150,7 +150,7 @@ typedef struct xfs_agi {
|
||||
#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp))
|
||||
|
||||
typedef struct xfs_agfl {
|
||||
xfs_agblock_t agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */
|
||||
__be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */
|
||||
} xfs_agfl_t;
|
||||
|
||||
/*
|
||||
|
@ -1477,8 +1477,10 @@ xfs_alloc_ag_vextent_small(
|
||||
/*
|
||||
* Can't allocate from the freelist for some reason.
|
||||
*/
|
||||
else
|
||||
else {
|
||||
fbno = NULLAGBLOCK;
|
||||
flen = 0;
|
||||
}
|
||||
/*
|
||||
* Can't do the allocation, give up.
|
||||
*/
|
||||
@ -2021,7 +2023,7 @@ xfs_alloc_get_freelist(
|
||||
/*
|
||||
* Get the block number and update the data structures.
|
||||
*/
|
||||
bno = INT_GET(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)], ARCH_CONVERT);
|
||||
bno = be32_to_cpu(agfl->agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
|
||||
be32_add(&agf->agf_flfirst, 1);
|
||||
xfs_trans_brelse(tp, agflbp);
|
||||
if (be32_to_cpu(agf->agf_flfirst) == XFS_AGFL_SIZE(mp))
|
||||
@ -2108,7 +2110,7 @@ xfs_alloc_put_freelist(
|
||||
{
|
||||
xfs_agf_t *agf; /* a.g. freespace structure */
|
||||
xfs_agfl_t *agfl; /* a.g. free block array */
|
||||
xfs_agblock_t *blockp;/* pointer to array entry */
|
||||
__be32 *blockp;/* pointer to array entry */
|
||||
int error;
|
||||
#ifdef XFS_ALLOC_TRACE
|
||||
static char fname[] = "xfs_alloc_put_freelist";
|
||||
@ -2132,7 +2134,7 @@ xfs_alloc_put_freelist(
|
||||
pag->pagf_flcount++;
|
||||
ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
|
||||
blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)];
|
||||
INT_SET(*blockp, ARCH_CONVERT, bno);
|
||||
*blockp = cpu_to_be32(bno);
|
||||
TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
|
||||
xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
|
||||
xfs_trans_log_buf(tp, agflbp,
|
||||
|
@ -92,6 +92,7 @@ xfs_alloc_delrec(
|
||||
xfs_alloc_key_t *rkp; /* right block key pointer */
|
||||
xfs_alloc_ptr_t *rpp; /* right block address pointer */
|
||||
int rrecs=0; /* number of records in right block */
|
||||
int numrecs;
|
||||
xfs_alloc_rec_t *rrp; /* right block record pointer */
|
||||
xfs_btree_cur_t *tcur; /* temporary btree cursor */
|
||||
|
||||
@ -115,7 +116,8 @@ xfs_alloc_delrec(
|
||||
/*
|
||||
* Fail if we're off the end of the block.
|
||||
*/
|
||||
if (ptr > be16_to_cpu(block->bb_numrecs)) {
|
||||
numrecs = be16_to_cpu(block->bb_numrecs);
|
||||
if (ptr > numrecs) {
|
||||
*stat = 0;
|
||||
return 0;
|
||||
}
|
||||
@ -129,18 +131,18 @@ xfs_alloc_delrec(
|
||||
lkp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
|
||||
lpp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = ptr; i < be16_to_cpu(block->bb_numrecs); i++) {
|
||||
for (i = ptr; i < numrecs; i++) {
|
||||
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(lpp[i]), level)))
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
if (ptr < be16_to_cpu(block->bb_numrecs)) {
|
||||
if (ptr < numrecs) {
|
||||
memmove(&lkp[ptr - 1], &lkp[ptr],
|
||||
(be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lkp));
|
||||
(numrecs - ptr) * sizeof(*lkp));
|
||||
memmove(&lpp[ptr - 1], &lpp[ptr],
|
||||
(be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lpp));
|
||||
xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
|
||||
xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
|
||||
(numrecs - ptr) * sizeof(*lpp));
|
||||
xfs_alloc_log_ptrs(cur, bp, ptr, numrecs - 1);
|
||||
xfs_alloc_log_keys(cur, bp, ptr, numrecs - 1);
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -149,10 +151,10 @@ xfs_alloc_delrec(
|
||||
*/
|
||||
else {
|
||||
lrp = XFS_ALLOC_REC_ADDR(block, 1, cur);
|
||||
if (ptr < be16_to_cpu(block->bb_numrecs)) {
|
||||
if (ptr < numrecs) {
|
||||
memmove(&lrp[ptr - 1], &lrp[ptr],
|
||||
(be16_to_cpu(block->bb_numrecs) - ptr) * sizeof(*lrp));
|
||||
xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs) - 1);
|
||||
(numrecs - ptr) * sizeof(*lrp));
|
||||
xfs_alloc_log_recs(cur, bp, ptr, numrecs - 1);
|
||||
}
|
||||
/*
|
||||
* If it's the first record in the block, we'll need a key
|
||||
@ -167,7 +169,8 @@ xfs_alloc_delrec(
|
||||
/*
|
||||
* Decrement and log the number of entries in the block.
|
||||
*/
|
||||
be16_add(&block->bb_numrecs, -1);
|
||||
numrecs--;
|
||||
block->bb_numrecs = cpu_to_be16(numrecs);
|
||||
xfs_alloc_log_block(cur->bc_tp, bp, XFS_BB_NUMRECS);
|
||||
/*
|
||||
* See if the longest free extent in the allocation group was
|
||||
@ -181,14 +184,14 @@ xfs_alloc_delrec(
|
||||
if (level == 0 &&
|
||||
cur->bc_btnum == XFS_BTNUM_CNT &&
|
||||
be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK &&
|
||||
ptr > be16_to_cpu(block->bb_numrecs)) {
|
||||
ASSERT(ptr == be16_to_cpu(block->bb_numrecs) + 1);
|
||||
ptr > numrecs) {
|
||||
ASSERT(ptr == numrecs + 1);
|
||||
/*
|
||||
* There are still records in the block. Grab the size
|
||||
* from the last one.
|
||||
*/
|
||||
if (be16_to_cpu(block->bb_numrecs)) {
|
||||
rrp = XFS_ALLOC_REC_ADDR(block, be16_to_cpu(block->bb_numrecs), cur);
|
||||
if (numrecs) {
|
||||
rrp = XFS_ALLOC_REC_ADDR(block, numrecs, cur);
|
||||
agf->agf_longest = rrp->ar_blockcount;
|
||||
}
|
||||
/*
|
||||
@ -211,7 +214,7 @@ xfs_alloc_delrec(
|
||||
* and it's NOT the leaf level,
|
||||
* then we can get rid of this level.
|
||||
*/
|
||||
if (be16_to_cpu(block->bb_numrecs) == 1 && level > 0) {
|
||||
if (numrecs == 1 && level > 0) {
|
||||
/*
|
||||
* lpp is still set to the first pointer in the block.
|
||||
* Make it the new root of the btree.
|
||||
@ -267,7 +270,7 @@ xfs_alloc_delrec(
|
||||
* If the number of records remaining in the block is at least
|
||||
* the minimum, we're done.
|
||||
*/
|
||||
if (be16_to_cpu(block->bb_numrecs) >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
|
||||
if (numrecs >= XFS_ALLOC_BLOCK_MINRECS(level, cur)) {
|
||||
if (level > 0 && (error = xfs_alloc_decrement(cur, level, &i)))
|
||||
return error;
|
||||
*stat = 1;
|
||||
@ -419,19 +422,21 @@ xfs_alloc_delrec(
|
||||
* See if we can join with the left neighbor block.
|
||||
*/
|
||||
if (lbno != NULLAGBLOCK &&
|
||||
lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
|
||||
lrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
|
||||
/*
|
||||
* Set "right" to be the starting block,
|
||||
* "left" to be the left neighbor.
|
||||
*/
|
||||
rbno = bno;
|
||||
right = block;
|
||||
rrecs = be16_to_cpu(right->bb_numrecs);
|
||||
rbp = bp;
|
||||
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
|
||||
cur->bc_private.a.agno, lbno, 0, &lbp,
|
||||
XFS_ALLOC_BTREE_REF)))
|
||||
return error;
|
||||
left = XFS_BUF_TO_ALLOC_BLOCK(lbp);
|
||||
lrecs = be16_to_cpu(left->bb_numrecs);
|
||||
if ((error = xfs_btree_check_sblock(cur, left, level, lbp)))
|
||||
return error;
|
||||
}
|
||||
@ -439,20 +444,21 @@ xfs_alloc_delrec(
|
||||
* If that won't work, see if we can join with the right neighbor block.
|
||||
*/
|
||||
else if (rbno != NULLAGBLOCK &&
|
||||
rrecs + be16_to_cpu(block->bb_numrecs) <=
|
||||
XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
|
||||
rrecs + numrecs <= XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
|
||||
/*
|
||||
* Set "left" to be the starting block,
|
||||
* "right" to be the right neighbor.
|
||||
*/
|
||||
lbno = bno;
|
||||
left = block;
|
||||
lrecs = be16_to_cpu(left->bb_numrecs);
|
||||
lbp = bp;
|
||||
if ((error = xfs_btree_read_bufs(mp, cur->bc_tp,
|
||||
cur->bc_private.a.agno, rbno, 0, &rbp,
|
||||
XFS_ALLOC_BTREE_REF)))
|
||||
return error;
|
||||
right = XFS_BUF_TO_ALLOC_BLOCK(rbp);
|
||||
rrecs = be16_to_cpu(right->bb_numrecs);
|
||||
if ((error = xfs_btree_check_sblock(cur, right, level, rbp)))
|
||||
return error;
|
||||
}
|
||||
@ -474,34 +480,28 @@ xfs_alloc_delrec(
|
||||
/*
|
||||
* It's a non-leaf. Move keys and pointers.
|
||||
*/
|
||||
lkp = XFS_ALLOC_KEY_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
|
||||
lpp = XFS_ALLOC_PTR_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
|
||||
lkp = XFS_ALLOC_KEY_ADDR(left, lrecs + 1, cur);
|
||||
lpp = XFS_ALLOC_PTR_ADDR(left, lrecs + 1, cur);
|
||||
rkp = XFS_ALLOC_KEY_ADDR(right, 1, cur);
|
||||
rpp = XFS_ALLOC_PTR_ADDR(right, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
|
||||
for (i = 0; i < rrecs; i++) {
|
||||
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(rpp[i]), level)))
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
memcpy(lkp, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*lkp));
|
||||
memcpy(lpp, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*lpp));
|
||||
xfs_alloc_log_keys(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
|
||||
be16_to_cpu(left->bb_numrecs) +
|
||||
be16_to_cpu(right->bb_numrecs));
|
||||
xfs_alloc_log_ptrs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
|
||||
be16_to_cpu(left->bb_numrecs) +
|
||||
be16_to_cpu(right->bb_numrecs));
|
||||
memcpy(lkp, rkp, rrecs * sizeof(*lkp));
|
||||
memcpy(lpp, rpp, rrecs * sizeof(*lpp));
|
||||
xfs_alloc_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
|
||||
xfs_alloc_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
|
||||
} else {
|
||||
/*
|
||||
* It's a leaf. Move records.
|
||||
*/
|
||||
lrp = XFS_ALLOC_REC_ADDR(left, be16_to_cpu(left->bb_numrecs) + 1, cur);
|
||||
lrp = XFS_ALLOC_REC_ADDR(left, lrecs + 1, cur);
|
||||
rrp = XFS_ALLOC_REC_ADDR(right, 1, cur);
|
||||
memcpy(lrp, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*lrp));
|
||||
xfs_alloc_log_recs(cur, lbp, be16_to_cpu(left->bb_numrecs) + 1,
|
||||
be16_to_cpu(left->bb_numrecs) +
|
||||
be16_to_cpu(right->bb_numrecs));
|
||||
memcpy(lrp, rrp, rrecs * sizeof(*lrp));
|
||||
xfs_alloc_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
|
||||
}
|
||||
/*
|
||||
* If we joined with the left neighbor, set the buffer in the
|
||||
@ -509,7 +509,7 @@ xfs_alloc_delrec(
|
||||
*/
|
||||
if (bp != lbp) {
|
||||
xfs_btree_setbuf(cur, level, lbp);
|
||||
cur->bc_ptrs[level] += be16_to_cpu(left->bb_numrecs);
|
||||
cur->bc_ptrs[level] += lrecs;
|
||||
}
|
||||
/*
|
||||
* If we joined with the right neighbor and there's a level above
|
||||
@ -521,7 +521,8 @@ xfs_alloc_delrec(
|
||||
/*
|
||||
* Fix up the number of records in the surviving block.
|
||||
*/
|
||||
be16_add(&left->bb_numrecs, be16_to_cpu(right->bb_numrecs));
|
||||
lrecs += rrecs;
|
||||
left->bb_numrecs = cpu_to_be16(lrecs);
|
||||
/*
|
||||
* Fix up the right block pointer in the surviving block, and log it.
|
||||
*/
|
||||
@ -608,6 +609,7 @@ xfs_alloc_insrec(
|
||||
xfs_btree_cur_t *ncur; /* new cursor to be used at next lvl */
|
||||
xfs_alloc_key_t nkey; /* new key value, from split */
|
||||
xfs_alloc_rec_t nrec; /* new record value, for caller */
|
||||
int numrecs;
|
||||
int optr; /* old ptr value */
|
||||
xfs_alloc_ptr_t *pp; /* pointer to btree addresses */
|
||||
int ptr; /* index in btree block for this rec */
|
||||
@ -653,13 +655,14 @@ xfs_alloc_insrec(
|
||||
*/
|
||||
bp = cur->bc_bufs[level];
|
||||
block = XFS_BUF_TO_ALLOC_BLOCK(bp);
|
||||
numrecs = be16_to_cpu(block->bb_numrecs);
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_sblock(cur, block, level, bp)))
|
||||
return error;
|
||||
/*
|
||||
* Check that the new entry is being inserted in the right place.
|
||||
*/
|
||||
if (ptr <= be16_to_cpu(block->bb_numrecs)) {
|
||||
if (ptr <= numrecs) {
|
||||
if (level == 0) {
|
||||
rp = XFS_ALLOC_REC_ADDR(block, ptr, cur);
|
||||
xfs_btree_check_rec(cur->bc_btnum, recp, rp);
|
||||
@ -670,12 +673,12 @@ xfs_alloc_insrec(
|
||||
}
|
||||
#endif
|
||||
nbno = NULLAGBLOCK;
|
||||
ncur = (xfs_btree_cur_t *)0;
|
||||
ncur = NULL;
|
||||
/*
|
||||
* If the block is full, we can't insert the new entry until we
|
||||
* make the block un-full.
|
||||
*/
|
||||
if (be16_to_cpu(block->bb_numrecs) == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
|
||||
if (numrecs == XFS_ALLOC_BLOCK_MAXRECS(level, cur)) {
|
||||
/*
|
||||
* First, try shifting an entry to the right neighbor.
|
||||
*/
|
||||
@ -729,6 +732,7 @@ xfs_alloc_insrec(
|
||||
* At this point we know there's room for our new entry in the block
|
||||
* we're pointing at.
|
||||
*/
|
||||
numrecs = be16_to_cpu(block->bb_numrecs);
|
||||
if (level > 0) {
|
||||
/*
|
||||
* It's a non-leaf entry. Make a hole for the new data
|
||||
@ -737,15 +741,15 @@ xfs_alloc_insrec(
|
||||
kp = XFS_ALLOC_KEY_ADDR(block, 1, cur);
|
||||
pp = XFS_ALLOC_PTR_ADDR(block, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = be16_to_cpu(block->bb_numrecs); i >= ptr; i--) {
|
||||
for (i = numrecs; i >= ptr; i--) {
|
||||
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(pp[i - 1]), level)))
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
memmove(&kp[ptr], &kp[ptr - 1],
|
||||
(be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*kp));
|
||||
(numrecs - ptr + 1) * sizeof(*kp));
|
||||
memmove(&pp[ptr], &pp[ptr - 1],
|
||||
(be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*pp));
|
||||
(numrecs - ptr + 1) * sizeof(*pp));
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
|
||||
return error;
|
||||
@ -755,11 +759,12 @@ xfs_alloc_insrec(
|
||||
*/
|
||||
kp[ptr - 1] = key;
|
||||
pp[ptr - 1] = cpu_to_be32(*bnop);
|
||||
be16_add(&block->bb_numrecs, 1);
|
||||
xfs_alloc_log_keys(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
|
||||
xfs_alloc_log_ptrs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
|
||||
numrecs++;
|
||||
block->bb_numrecs = cpu_to_be16(numrecs);
|
||||
xfs_alloc_log_keys(cur, bp, ptr, numrecs);
|
||||
xfs_alloc_log_ptrs(cur, bp, ptr, numrecs);
|
||||
#ifdef DEBUG
|
||||
if (ptr < be16_to_cpu(block->bb_numrecs))
|
||||
if (ptr < numrecs)
|
||||
xfs_btree_check_key(cur->bc_btnum, kp + ptr - 1,
|
||||
kp + ptr);
|
||||
#endif
|
||||
@ -769,16 +774,17 @@ xfs_alloc_insrec(
|
||||
*/
|
||||
rp = XFS_ALLOC_REC_ADDR(block, 1, cur);
|
||||
memmove(&rp[ptr], &rp[ptr - 1],
|
||||
(be16_to_cpu(block->bb_numrecs) - ptr + 1) * sizeof(*rp));
|
||||
(numrecs - ptr + 1) * sizeof(*rp));
|
||||
/*
|
||||
* Now stuff the new record in, bump numrecs
|
||||
* and log the new data.
|
||||
*/
|
||||
rp[ptr - 1] = *recp; /* INT_: struct copy */
|
||||
be16_add(&block->bb_numrecs, 1);
|
||||
xfs_alloc_log_recs(cur, bp, ptr, be16_to_cpu(block->bb_numrecs));
|
||||
rp[ptr - 1] = *recp;
|
||||
numrecs++;
|
||||
block->bb_numrecs = cpu_to_be16(numrecs);
|
||||
xfs_alloc_log_recs(cur, bp, ptr, numrecs);
|
||||
#ifdef DEBUG
|
||||
if (ptr < be16_to_cpu(block->bb_numrecs))
|
||||
if (ptr < numrecs)
|
||||
xfs_btree_check_rec(cur->bc_btnum, rp + ptr - 1,
|
||||
rp + ptr);
|
||||
#endif
|
||||
@ -819,8 +825,8 @@ xfs_alloc_insrec(
|
||||
*/
|
||||
*bnop = nbno;
|
||||
if (nbno != NULLAGBLOCK) {
|
||||
*recp = nrec; /* INT_: struct copy */
|
||||
*curp = ncur; /* INT_: struct copy */
|
||||
*recp = nrec;
|
||||
*curp = ncur;
|
||||
}
|
||||
*stat = 1;
|
||||
return 0;
|
||||
@ -981,7 +987,7 @@ xfs_alloc_lookup(
|
||||
*/
|
||||
bp = cur->bc_bufs[level];
|
||||
if (bp && XFS_BUF_ADDR(bp) != d)
|
||||
bp = (xfs_buf_t *)0;
|
||||
bp = NULL;
|
||||
if (!bp) {
|
||||
/*
|
||||
* Need to get a new buffer. Read it, then
|
||||
@ -1229,7 +1235,7 @@ xfs_alloc_lshift(
|
||||
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
|
||||
return error;
|
||||
#endif
|
||||
*lpp = *rpp; /* INT_: copy */
|
||||
*lpp = *rpp;
|
||||
xfs_alloc_log_ptrs(cur, lbp, nrec, nrec);
|
||||
xfs_btree_check_key(cur->bc_btnum, lkp - 1, lkp);
|
||||
}
|
||||
@ -1406,8 +1412,8 @@ xfs_alloc_newroot(
|
||||
|
||||
kp = XFS_ALLOC_KEY_ADDR(new, 1, cur);
|
||||
if (be16_to_cpu(left->bb_level) > 0) {
|
||||
kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); /* INT_: structure copy */
|
||||
kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);/* INT_: structure copy */
|
||||
kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur);
|
||||
kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur);
|
||||
} else {
|
||||
xfs_alloc_rec_t *rp; /* btree record pointer */
|
||||
|
||||
@ -1527,8 +1533,8 @@ xfs_alloc_rshift(
|
||||
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
|
||||
return error;
|
||||
#endif
|
||||
*rkp = *lkp; /* INT_: copy */
|
||||
*rpp = *lpp; /* INT_: copy */
|
||||
*rkp = *lkp;
|
||||
*rpp = *lpp;
|
||||
xfs_alloc_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
|
||||
xfs_alloc_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
|
||||
xfs_btree_check_key(cur->bc_btnum, rkp, rkp + 1);
|
||||
@ -2044,7 +2050,7 @@ xfs_alloc_insert(
|
||||
nbno = NULLAGBLOCK;
|
||||
nrec.ar_startblock = cpu_to_be32(cur->bc_rec.a.ar_startblock);
|
||||
nrec.ar_blockcount = cpu_to_be32(cur->bc_rec.a.ar_blockcount);
|
||||
ncur = (xfs_btree_cur_t *)0;
|
||||
ncur = NULL;
|
||||
pcur = cur;
|
||||
/*
|
||||
* Loop going up the tree, starting at the leaf level.
|
||||
@ -2076,7 +2082,7 @@ xfs_alloc_insert(
|
||||
*/
|
||||
if (ncur) {
|
||||
pcur = ncur;
|
||||
ncur = (xfs_btree_cur_t *)0;
|
||||
ncur = NULL;
|
||||
}
|
||||
} while (nbno != NULLAGBLOCK);
|
||||
*stat = i;
|
||||
|
@ -91,7 +91,6 @@ STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
|
||||
/*
|
||||
* Routines to manipulate out-of-line attribute values.
|
||||
*/
|
||||
STATIC int xfs_attr_rmtval_get(xfs_da_args_t *args);
|
||||
STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args);
|
||||
STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args);
|
||||
|
||||
@ -180,7 +179,7 @@ xfs_attr_get(bhv_desc_t *bdp, const char *name, char *value, int *valuelenp,
|
||||
return(error);
|
||||
}
|
||||
|
||||
STATIC int
|
||||
int
|
||||
xfs_attr_set_int(xfs_inode_t *dp, const char *name, int namelen,
|
||||
char *value, int valuelen, int flags)
|
||||
{
|
||||
@ -440,7 +439,7 @@ xfs_attr_set(bhv_desc_t *bdp, const char *name, char *value, int valuelen, int f
|
||||
* Generic handler routine to remove a name from an attribute list.
|
||||
* Transitions attribute list from Btree to shortform as necessary.
|
||||
*/
|
||||
STATIC int
|
||||
int
|
||||
xfs_attr_remove_int(xfs_inode_t *dp, const char *name, int namelen, int flags)
|
||||
{
|
||||
xfs_da_args_t args;
|
||||
@ -591,6 +590,110 @@ xfs_attr_remove(bhv_desc_t *bdp, const char *name, int flags, struct cred *cred)
|
||||
return xfs_attr_remove_int(dp, name, namelen, flags);
|
||||
}
|
||||
|
||||
int /* error */
|
||||
xfs_attr_list_int(xfs_attr_list_context_t *context)
|
||||
{
|
||||
int error;
|
||||
xfs_inode_t *dp = context->dp;
|
||||
|
||||
/*
|
||||
* Decide on what work routines to call based on the inode size.
|
||||
*/
|
||||
if (XFS_IFORK_Q(dp) == 0 ||
|
||||
(dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
|
||||
dp->i_d.di_anextents == 0)) {
|
||||
error = 0;
|
||||
} else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
|
||||
error = xfs_attr_shortform_list(context);
|
||||
} else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
|
||||
error = xfs_attr_leaf_list(context);
|
||||
} else {
|
||||
error = xfs_attr_node_list(context);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \
|
||||
(((struct attrlist_ent *) 0)->a_name - (char *) 0)
|
||||
#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \
|
||||
((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
|
||||
& ~(sizeof(u_int32_t)-1))
|
||||
|
||||
/*
|
||||
* Format an attribute and copy it out to the user's buffer.
|
||||
* Take care to check values and protect against them changing later,
|
||||
* we may be reading them directly out of a user buffer.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
xfs_attr_put_listent(xfs_attr_list_context_t *context, attrnames_t *namesp,
|
||||
char *name, int namelen,
|
||||
int valuelen, char *value)
|
||||
{
|
||||
attrlist_ent_t *aep;
|
||||
int arraytop;
|
||||
|
||||
ASSERT(!(context->flags & ATTR_KERNOVAL));
|
||||
ASSERT(context->count >= 0);
|
||||
ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
|
||||
ASSERT(context->firstu >= sizeof(*context->alist));
|
||||
ASSERT(context->firstu <= context->bufsize);
|
||||
|
||||
arraytop = sizeof(*context->alist) +
|
||||
context->count * sizeof(context->alist->al_offset[0]);
|
||||
context->firstu -= ATTR_ENTSIZE(namelen);
|
||||
if (context->firstu < arraytop) {
|
||||
xfs_attr_trace_l_c("buffer full", context);
|
||||
context->alist->al_more = 1;
|
||||
context->seen_enough = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]);
|
||||
aep->a_valuelen = valuelen;
|
||||
memcpy(aep->a_name, name, namelen);
|
||||
aep->a_name[ namelen ] = 0;
|
||||
context->alist->al_offset[ context->count++ ] = context->firstu;
|
||||
context->alist->al_count = context->count;
|
||||
xfs_attr_trace_l_c("add", context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_attr_kern_list(xfs_attr_list_context_t *context, attrnames_t *namesp,
|
||||
char *name, int namelen,
|
||||
int valuelen, char *value)
|
||||
{
|
||||
char *offset;
|
||||
int arraytop;
|
||||
|
||||
ASSERT(context->count >= 0);
|
||||
|
||||
arraytop = context->count + namesp->attr_namelen + namelen + 1;
|
||||
if (arraytop > context->firstu) {
|
||||
context->count = -1; /* insufficient space */
|
||||
return 1;
|
||||
}
|
||||
offset = (char *)context->alist + context->count;
|
||||
strncpy(offset, namesp->attr_name, namesp->attr_namelen);
|
||||
offset += namesp->attr_namelen;
|
||||
strncpy(offset, name, namelen); /* real name */
|
||||
offset += namelen;
|
||||
*offset = '\0';
|
||||
context->count += namesp->attr_namelen + namelen + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
xfs_attr_kern_list_sizes(xfs_attr_list_context_t *context, attrnames_t *namesp,
|
||||
char *name, int namelen,
|
||||
int valuelen, char *value)
|
||||
{
|
||||
context->count += namesp->attr_namelen + namelen + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a list of extended attribute names and optionally
|
||||
* also value lengths. Positive return value follows the XFS
|
||||
@ -615,13 +718,13 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
|
||||
return(XFS_ERROR(EINVAL));
|
||||
if ((cursor->initted == 0) &&
|
||||
(cursor->hashval || cursor->blkno || cursor->offset))
|
||||
return(XFS_ERROR(EINVAL));
|
||||
return XFS_ERROR(EINVAL);
|
||||
|
||||
/*
|
||||
* Check for a properly aligned buffer.
|
||||
*/
|
||||
if (((long)buffer) & (sizeof(int)-1))
|
||||
return(XFS_ERROR(EFAULT));
|
||||
return XFS_ERROR(EFAULT);
|
||||
if (flags & ATTR_KERNOVAL)
|
||||
bufsize = 0;
|
||||
|
||||
@ -634,53 +737,47 @@ xfs_attr_list(bhv_desc_t *bdp, char *buffer, int bufsize, int flags,
|
||||
context.dupcnt = 0;
|
||||
context.resynch = 1;
|
||||
context.flags = flags;
|
||||
if (!(flags & ATTR_KERNAMELS)) {
|
||||
context.seen_enough = 0;
|
||||
context.alist = (attrlist_t *)buffer;
|
||||
context.put_value = 0;
|
||||
|
||||
if (flags & ATTR_KERNAMELS) {
|
||||
context.bufsize = bufsize;
|
||||
context.firstu = context.bufsize;
|
||||
if (flags & ATTR_KERNOVAL)
|
||||
context.put_listent = xfs_attr_kern_list_sizes;
|
||||
else
|
||||
context.put_listent = xfs_attr_kern_list;
|
||||
} else {
|
||||
context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */
|
||||
context.firstu = context.bufsize;
|
||||
context.alist = (attrlist_t *)buffer;
|
||||
context.alist->al_count = 0;
|
||||
context.alist->al_more = 0;
|
||||
context.alist->al_offset[0] = context.bufsize;
|
||||
}
|
||||
else {
|
||||
context.bufsize = bufsize;
|
||||
context.firstu = context.bufsize;
|
||||
context.alist = (attrlist_t *)buffer;
|
||||
context.put_listent = xfs_attr_put_listent;
|
||||
}
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
|
||||
return (EIO);
|
||||
return EIO;
|
||||
|
||||
xfs_ilock(dp, XFS_ILOCK_SHARED);
|
||||
/*
|
||||
* Decide on what work routines to call based on the inode size.
|
||||
*/
|
||||
xfs_attr_trace_l_c("syscall start", &context);
|
||||
if (XFS_IFORK_Q(dp) == 0 ||
|
||||
(dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
|
||||
dp->i_d.di_anextents == 0)) {
|
||||
error = 0;
|
||||
} else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
|
||||
error = xfs_attr_shortform_list(&context);
|
||||
} else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
|
||||
error = xfs_attr_leaf_list(&context);
|
||||
} else {
|
||||
error = xfs_attr_node_list(&context);
|
||||
}
|
||||
|
||||
error = xfs_attr_list_int(&context);
|
||||
|
||||
xfs_iunlock(dp, XFS_ILOCK_SHARED);
|
||||
xfs_attr_trace_l_c("syscall end", &context);
|
||||
|
||||
if (!(context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS))) {
|
||||
ASSERT(error >= 0);
|
||||
}
|
||||
else { /* must return negated buffer size or the error */
|
||||
if (context.flags & (ATTR_KERNOVAL|ATTR_KERNAMELS)) {
|
||||
/* must return negated buffer size or the error */
|
||||
if (context.count < 0)
|
||||
error = XFS_ERROR(ERANGE);
|
||||
else
|
||||
error = -context.count;
|
||||
}
|
||||
} else
|
||||
ASSERT(error >= 0);
|
||||
|
||||
return(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
int /* error */
|
||||
@ -1122,19 +1219,19 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
|
||||
context->cursor->blkno = 0;
|
||||
error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK);
|
||||
if (error)
|
||||
return(error);
|
||||
return XFS_ERROR(error);
|
||||
ASSERT(bp != NULL);
|
||||
leaf = bp->data;
|
||||
if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) {
|
||||
XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
|
||||
context->dp->i_mount, leaf);
|
||||
xfs_da_brelse(NULL, bp);
|
||||
return(XFS_ERROR(EFSCORRUPTED));
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
|
||||
(void)xfs_attr_leaf_list_int(bp, context);
|
||||
error = xfs_attr_leaf_list_int(bp, context);
|
||||
xfs_da_brelse(NULL, bp);
|
||||
return(0);
|
||||
return XFS_ERROR(error);
|
||||
}
|
||||
|
||||
|
||||
@ -1858,8 +1955,12 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
||||
return(XFS_ERROR(EFSCORRUPTED));
|
||||
}
|
||||
error = xfs_attr_leaf_list_int(bp, context);
|
||||
if (error || !leaf->hdr.info.forw)
|
||||
break; /* not really an error, buffer full or EOF */
|
||||
if (error) {
|
||||
xfs_da_brelse(NULL, bp);
|
||||
return error;
|
||||
}
|
||||
if (context->seen_enough || leaf->hdr.info.forw == 0)
|
||||
break;
|
||||
cursor->blkno = be32_to_cpu(leaf->hdr.info.forw);
|
||||
xfs_da_brelse(NULL, bp);
|
||||
error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
|
||||
@ -1886,7 +1987,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
|
||||
* Read the value associated with an attribute from the out-of-line buffer
|
||||
* that we stored it in.
|
||||
*/
|
||||
STATIC int
|
||||
int
|
||||
xfs_attr_rmtval_get(xfs_da_args_t *args)
|
||||
{
|
||||
xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE];
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
struct cred;
|
||||
struct bhv_vnode;
|
||||
struct xfs_attr_list_context;
|
||||
|
||||
typedef int (*attrset_t)(struct bhv_vnode *, char *, void *, size_t, int);
|
||||
typedef int (*attrget_t)(struct bhv_vnode *, char *, void *, size_t, int);
|
||||
@ -160,13 +161,16 @@ struct xfs_da_args;
|
||||
*/
|
||||
int xfs_attr_get(bhv_desc_t *, const char *, char *, int *, int, struct cred *);
|
||||
int xfs_attr_set(bhv_desc_t *, const char *, char *, int, int, struct cred *);
|
||||
int xfs_attr_set_int(struct xfs_inode *, const char *, int, char *, int, int);
|
||||
int xfs_attr_remove(bhv_desc_t *, const char *, int, struct cred *);
|
||||
int xfs_attr_list(bhv_desc_t *, char *, int, int,
|
||||
struct attrlist_cursor_kern *, struct cred *);
|
||||
int xfs_attr_remove_int(struct xfs_inode *, const char *, int, int);
|
||||
int xfs_attr_list(bhv_desc_t *, char *, int, int, struct attrlist_cursor_kern *, struct cred *);
|
||||
int xfs_attr_list_int(struct xfs_attr_list_context *);
|
||||
int xfs_attr_inactive(struct xfs_inode *dp);
|
||||
|
||||
int xfs_attr_shortform_getvalue(struct xfs_da_args *);
|
||||
int xfs_attr_fetch(struct xfs_inode *, const char *, int,
|
||||
char *, int *, int, struct cred *);
|
||||
int xfs_attr_rmtval_get(struct xfs_da_args *args);
|
||||
|
||||
#endif /* __XFS_ATTR_H__ */
|
||||
|
@ -89,9 +89,46 @@ STATIC void xfs_attr_leaf_moveents(xfs_attr_leafblock_t *src_leaf,
|
||||
int dst_start, int move_count,
|
||||
xfs_mount_t *mp);
|
||||
STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
|
||||
STATIC int xfs_attr_put_listent(xfs_attr_list_context_t *context,
|
||||
attrnames_t *, char *name, int namelen,
|
||||
int valuelen);
|
||||
|
||||
/*========================================================================
|
||||
* Namespace helper routines
|
||||
*========================================================================*/
|
||||
|
||||
STATIC inline attrnames_t *
|
||||
xfs_attr_flags_namesp(int flags)
|
||||
{
|
||||
return ((flags & XFS_ATTR_SECURE) ? &attr_secure:
|
||||
((flags & XFS_ATTR_ROOT) ? &attr_trusted : &attr_user));
|
||||
}
|
||||
|
||||
/*
|
||||
* If namespace bits don't match return 0.
|
||||
* If all match then return 1.
|
||||
*/
|
||||
STATIC inline int
|
||||
xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
|
||||
{
|
||||
return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* If namespace bits don't match and we don't have an override for it
|
||||
* then return 0.
|
||||
* If all match or are overridable then return 1.
|
||||
*/
|
||||
STATIC inline int
|
||||
xfs_attr_namesp_match_overrides(int arg_flags, int ondisk_flags)
|
||||
{
|
||||
if (((arg_flags & ATTR_SECURE) == 0) !=
|
||||
((ondisk_flags & XFS_ATTR_SECURE) == 0) &&
|
||||
!(arg_flags & ATTR_KERNORMALS))
|
||||
return 0;
|
||||
if (((arg_flags & ATTR_ROOT) == 0) !=
|
||||
((ondisk_flags & XFS_ATTR_ROOT) == 0) &&
|
||||
!(arg_flags & ATTR_KERNROOTLS))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*========================================================================
|
||||
@ -228,11 +265,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
|
||||
continue;
|
||||
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
|
||||
continue;
|
||||
if (((args->flags & ATTR_SECURE) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_SECURE) != 0))
|
||||
continue;
|
||||
if (((args->flags & ATTR_ROOT) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_ROOT) != 0))
|
||||
if (!xfs_attr_namesp_match(args->flags, sfe->flags))
|
||||
continue;
|
||||
ASSERT(0);
|
||||
#endif
|
||||
@ -246,8 +279,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
|
||||
|
||||
sfe->namelen = args->namelen;
|
||||
sfe->valuelen = args->valuelen;
|
||||
sfe->flags = (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
|
||||
((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
|
||||
sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
|
||||
memcpy(sfe->nameval, args->name, args->namelen);
|
||||
memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
|
||||
sf->hdr.count++;
|
||||
@ -282,11 +314,7 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
|
||||
continue;
|
||||
if (memcmp(sfe->nameval, args->name, args->namelen) != 0)
|
||||
continue;
|
||||
if (((args->flags & ATTR_SECURE) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_SECURE) != 0))
|
||||
continue;
|
||||
if (((args->flags & ATTR_ROOT) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_ROOT) != 0))
|
||||
if (!xfs_attr_namesp_match(args->flags, sfe->flags))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
@ -363,11 +391,7 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
|
||||
continue;
|
||||
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
|
||||
continue;
|
||||
if (((args->flags & ATTR_SECURE) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_SECURE) != 0))
|
||||
continue;
|
||||
if (((args->flags & ATTR_ROOT) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_ROOT) != 0))
|
||||
if (!xfs_attr_namesp_match(args->flags, sfe->flags))
|
||||
continue;
|
||||
return(XFS_ERROR(EEXIST));
|
||||
}
|
||||
@ -394,11 +418,7 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args)
|
||||
continue;
|
||||
if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
|
||||
continue;
|
||||
if (((args->flags & ATTR_SECURE) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_SECURE) != 0))
|
||||
continue;
|
||||
if (((args->flags & ATTR_ROOT) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_ROOT) != 0))
|
||||
if (!xfs_attr_namesp_match(args->flags, sfe->flags))
|
||||
continue;
|
||||
if (args->flags & ATTR_KERNOVAL) {
|
||||
args->valuelen = sfe->valuelen;
|
||||
@ -485,8 +505,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
|
||||
nargs.valuelen = sfe->valuelen;
|
||||
nargs.hashval = xfs_da_hashname((char *)sfe->nameval,
|
||||
sfe->namelen);
|
||||
nargs.flags = (sfe->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
|
||||
((sfe->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
|
||||
nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags);
|
||||
error = xfs_attr_leaf_lookup_int(bp, &nargs); /* set a->index */
|
||||
ASSERT(error == ENOATTR);
|
||||
error = xfs_attr_leaf_add(bp, &nargs);
|
||||
@ -520,6 +539,10 @@ xfs_attr_shortform_compare(const void *a, const void *b)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define XFS_ISRESET_CURSOR(cursor) \
|
||||
(!((cursor)->initted) && !((cursor)->hashval) && \
|
||||
!((cursor)->blkno) && !((cursor)->offset))
|
||||
/*
|
||||
* Copy out entries of shortform attribute lists for attr_list().
|
||||
* Shortform attribute lists are not stored in hashval sorted order.
|
||||
@ -537,6 +560,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
|
||||
xfs_attr_sf_entry_t *sfe;
|
||||
xfs_inode_t *dp;
|
||||
int sbsize, nsbuf, count, i;
|
||||
int error;
|
||||
|
||||
ASSERT(context != NULL);
|
||||
dp = context->dp;
|
||||
@ -552,46 +576,51 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
|
||||
xfs_attr_trace_l_c("sf start", context);
|
||||
|
||||
/*
|
||||
* If the buffer is large enough, do not bother with sorting.
|
||||
* If the buffer is large enough and the cursor is at the start,
|
||||
* do not bother with sorting since we will return everything in
|
||||
* one buffer and another call using the cursor won't need to be
|
||||
* made.
|
||||
* Note the generous fudge factor of 16 overhead bytes per entry.
|
||||
* If bufsize is zero then put_listent must be a search function
|
||||
* and can just scan through what we have.
|
||||
*/
|
||||
if ((dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize) {
|
||||
if (context->bufsize == 0 ||
|
||||
(XFS_ISRESET_CURSOR(cursor) &&
|
||||
(dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
|
||||
for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
|
||||
attrnames_t *namesp;
|
||||
|
||||
if (((context->flags & ATTR_SECURE) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_SECURE) != 0) &&
|
||||
!(context->flags & ATTR_KERNORMALS)) {
|
||||
if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
|
||||
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
|
||||
continue;
|
||||
}
|
||||
if (((context->flags & ATTR_ROOT) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_ROOT) != 0) &&
|
||||
!(context->flags & ATTR_KERNROOTLS)) {
|
||||
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
|
||||
continue;
|
||||
}
|
||||
namesp = (sfe->flags & XFS_ATTR_SECURE) ? &attr_secure:
|
||||
((sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted :
|
||||
&attr_user);
|
||||
if (context->flags & ATTR_KERNOVAL) {
|
||||
ASSERT(context->flags & ATTR_KERNAMELS);
|
||||
context->count += namesp->attr_namelen +
|
||||
sfe->namelen + 1;
|
||||
}
|
||||
else {
|
||||
if (xfs_attr_put_listent(context, namesp,
|
||||
(char *)sfe->nameval,
|
||||
(int)sfe->namelen,
|
||||
(int)sfe->valuelen))
|
||||
break;
|
||||
}
|
||||
namesp = xfs_attr_flags_namesp(sfe->flags);
|
||||
error = context->put_listent(context,
|
||||
namesp,
|
||||
(char *)sfe->nameval,
|
||||
(int)sfe->namelen,
|
||||
(int)sfe->valuelen,
|
||||
(char*)&sfe->nameval[sfe->namelen]);
|
||||
|
||||
/*
|
||||
* Either search callback finished early or
|
||||
* didn't fit it all in the buffer after all.
|
||||
*/
|
||||
if (context->seen_enough)
|
||||
break;
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
|
||||
}
|
||||
xfs_attr_trace_l_c("sf big-gulp", context);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* do no more for a search callback */
|
||||
if (context->bufsize == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* It didn't all fit, so we have to sort everything on hashval.
|
||||
*/
|
||||
@ -614,15 +643,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
|
||||
kmem_free(sbuf, sbsize);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
if (((context->flags & ATTR_SECURE) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_SECURE) != 0) &&
|
||||
!(context->flags & ATTR_KERNORMALS)) {
|
||||
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
|
||||
continue;
|
||||
}
|
||||
if (((context->flags & ATTR_ROOT) != 0) !=
|
||||
((sfe->flags & XFS_ATTR_ROOT) != 0) &&
|
||||
!(context->flags & ATTR_KERNROOTLS)) {
|
||||
if (!xfs_attr_namesp_match_overrides(context->flags, sfe->flags)) {
|
||||
sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
|
||||
continue;
|
||||
}
|
||||
@ -671,24 +692,22 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
|
||||
for ( ; i < nsbuf; i++, sbp++) {
|
||||
attrnames_t *namesp;
|
||||
|
||||
namesp = (sbp->flags & XFS_ATTR_SECURE) ? &attr_secure :
|
||||
((sbp->flags & XFS_ATTR_ROOT) ? &attr_trusted :
|
||||
&attr_user);
|
||||
namesp = xfs_attr_flags_namesp(sbp->flags);
|
||||
|
||||
if (cursor->hashval != sbp->hash) {
|
||||
cursor->hashval = sbp->hash;
|
||||
cursor->offset = 0;
|
||||
}
|
||||
if (context->flags & ATTR_KERNOVAL) {
|
||||
ASSERT(context->flags & ATTR_KERNAMELS);
|
||||
context->count += namesp->attr_namelen +
|
||||
sbp->namelen + 1;
|
||||
} else {
|
||||
if (xfs_attr_put_listent(context, namesp,
|
||||
sbp->name, sbp->namelen,
|
||||
sbp->valuelen))
|
||||
break;
|
||||
}
|
||||
error = context->put_listent(context,
|
||||
namesp,
|
||||
sbp->name,
|
||||
sbp->namelen,
|
||||
sbp->valuelen,
|
||||
&sbp->name[sbp->namelen]);
|
||||
if (error)
|
||||
return error;
|
||||
if (context->seen_enough)
|
||||
break;
|
||||
cursor->offset++;
|
||||
}
|
||||
|
||||
@ -810,8 +829,7 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
|
||||
nargs.value = (char *)&name_loc->nameval[nargs.namelen];
|
||||
nargs.valuelen = be16_to_cpu(name_loc->valuelen);
|
||||
nargs.hashval = be32_to_cpu(entry->hashval);
|
||||
nargs.flags = (entry->flags & XFS_ATTR_SECURE) ? ATTR_SECURE :
|
||||
((entry->flags & XFS_ATTR_ROOT) ? ATTR_ROOT : 0);
|
||||
nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags);
|
||||
xfs_attr_shortform_add(&nargs, forkoff);
|
||||
}
|
||||
error = 0;
|
||||
@ -1098,8 +1116,7 @@ xfs_attr_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int mapindex)
|
||||
be16_to_cpu(map->size));
|
||||
entry->hashval = cpu_to_be32(args->hashval);
|
||||
entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
|
||||
entry->flags |= (args->flags & ATTR_SECURE) ? XFS_ATTR_SECURE :
|
||||
((args->flags & ATTR_ROOT) ? XFS_ATTR_ROOT : 0);
|
||||
entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
|
||||
if (args->rename) {
|
||||
entry->flags |= XFS_ATTR_INCOMPLETE;
|
||||
if ((args->blkno2 == args->blkno) &&
|
||||
@ -1926,7 +1943,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
|
||||
else
|
||||
break;
|
||||
}
|
||||
ASSERT((probe >= 0) &&
|
||||
ASSERT((probe >= 0) &&
|
||||
(!leaf->hdr.count
|
||||
|| (probe < be16_to_cpu(leaf->hdr.count))));
|
||||
ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval));
|
||||
@ -1971,14 +1988,9 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
|
||||
name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, probe);
|
||||
if (name_loc->namelen != args->namelen)
|
||||
continue;
|
||||
if (memcmp(args->name, (char *)name_loc->nameval,
|
||||
args->namelen) != 0)
|
||||
if (memcmp(args->name, (char *)name_loc->nameval, args->namelen) != 0)
|
||||
continue;
|
||||
if (((args->flags & ATTR_SECURE) != 0) !=
|
||||
((entry->flags & XFS_ATTR_SECURE) != 0))
|
||||
continue;
|
||||
if (((args->flags & ATTR_ROOT) != 0) !=
|
||||
((entry->flags & XFS_ATTR_ROOT) != 0))
|
||||
if (!xfs_attr_namesp_match(args->flags, entry->flags))
|
||||
continue;
|
||||
args->index = probe;
|
||||
return(XFS_ERROR(EEXIST));
|
||||
@ -1989,11 +2001,7 @@ xfs_attr_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args)
|
||||
if (memcmp(args->name, (char *)name_rmt->name,
|
||||
args->namelen) != 0)
|
||||
continue;
|
||||
if (((args->flags & ATTR_SECURE) != 0) !=
|
||||
((entry->flags & XFS_ATTR_SECURE) != 0))
|
||||
continue;
|
||||
if (((args->flags & ATTR_ROOT) != 0) !=
|
||||
((entry->flags & XFS_ATTR_ROOT) != 0))
|
||||
if (!xfs_attr_namesp_match(args->flags, entry->flags))
|
||||
continue;
|
||||
args->index = probe;
|
||||
args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
|
||||
@ -2312,8 +2320,6 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
|
||||
attrlist_cursor_kern_t *cursor;
|
||||
xfs_attr_leafblock_t *leaf;
|
||||
xfs_attr_leaf_entry_t *entry;
|
||||
xfs_attr_leaf_name_local_t *name_loc;
|
||||
xfs_attr_leaf_name_remote_t *name_rmt;
|
||||
int retval, i;
|
||||
|
||||
ASSERT(bp != NULL);
|
||||
@ -2355,9 +2361,8 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
|
||||
* We have found our place, start copying out the new attributes.
|
||||
*/
|
||||
retval = 0;
|
||||
for ( ; (i < be16_to_cpu(leaf->hdr.count))
|
||||
&& (retval == 0); entry++, i++) {
|
||||
attrnames_t *namesp;
|
||||
for ( ; (i < be16_to_cpu(leaf->hdr.count)); entry++, i++) {
|
||||
attrnames_t *namesp;
|
||||
|
||||
if (be32_to_cpu(entry->hashval) != cursor->hashval) {
|
||||
cursor->hashval = be32_to_cpu(entry->hashval);
|
||||
@ -2366,115 +2371,69 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context)
|
||||
|
||||
if (entry->flags & XFS_ATTR_INCOMPLETE)
|
||||
continue; /* skip incomplete entries */
|
||||
if (((context->flags & ATTR_SECURE) != 0) !=
|
||||
((entry->flags & XFS_ATTR_SECURE) != 0) &&
|
||||
!(context->flags & ATTR_KERNORMALS))
|
||||
continue; /* skip non-matching entries */
|
||||
if (((context->flags & ATTR_ROOT) != 0) !=
|
||||
((entry->flags & XFS_ATTR_ROOT) != 0) &&
|
||||
!(context->flags & ATTR_KERNROOTLS))
|
||||
continue; /* skip non-matching entries */
|
||||
if (!xfs_attr_namesp_match_overrides(context->flags, entry->flags))
|
||||
continue;
|
||||
|
||||
namesp = (entry->flags & XFS_ATTR_SECURE) ? &attr_secure :
|
||||
((entry->flags & XFS_ATTR_ROOT) ? &attr_trusted :
|
||||
&attr_user);
|
||||
namesp = xfs_attr_flags_namesp(entry->flags);
|
||||
|
||||
if (entry->flags & XFS_ATTR_LOCAL) {
|
||||
name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
|
||||
if (context->flags & ATTR_KERNOVAL) {
|
||||
ASSERT(context->flags & ATTR_KERNAMELS);
|
||||
context->count += namesp->attr_namelen +
|
||||
(int)name_loc->namelen + 1;
|
||||
} else {
|
||||
retval = xfs_attr_put_listent(context, namesp,
|
||||
(char *)name_loc->nameval,
|
||||
(int)name_loc->namelen,
|
||||
be16_to_cpu(name_loc->valuelen));
|
||||
}
|
||||
xfs_attr_leaf_name_local_t *name_loc =
|
||||
XFS_ATTR_LEAF_NAME_LOCAL(leaf, i);
|
||||
|
||||
retval = context->put_listent(context,
|
||||
namesp,
|
||||
(char *)name_loc->nameval,
|
||||
(int)name_loc->namelen,
|
||||
be16_to_cpu(name_loc->valuelen),
|
||||
(char *)&name_loc->nameval[name_loc->namelen]);
|
||||
if (retval)
|
||||
return retval;
|
||||
} else {
|
||||
name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
|
||||
if (context->flags & ATTR_KERNOVAL) {
|
||||
ASSERT(context->flags & ATTR_KERNAMELS);
|
||||
context->count += namesp->attr_namelen +
|
||||
(int)name_rmt->namelen + 1;
|
||||
} else {
|
||||
retval = xfs_attr_put_listent(context, namesp,
|
||||
(char *)name_rmt->name,
|
||||
(int)name_rmt->namelen,
|
||||
be32_to_cpu(name_rmt->valuelen));
|
||||
xfs_attr_leaf_name_remote_t *name_rmt =
|
||||
XFS_ATTR_LEAF_NAME_REMOTE(leaf, i);
|
||||
|
||||
int valuelen = be32_to_cpu(name_rmt->valuelen);
|
||||
|
||||
if (context->put_value) {
|
||||
xfs_da_args_t args;
|
||||
|
||||
memset((char *)&args, 0, sizeof(args));
|
||||
args.dp = context->dp;
|
||||
args.whichfork = XFS_ATTR_FORK;
|
||||
args.valuelen = valuelen;
|
||||
args.value = kmem_alloc(valuelen, KM_SLEEP);
|
||||
args.rmtblkno = be32_to_cpu(name_rmt->valueblk);
|
||||
args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen);
|
||||
retval = xfs_attr_rmtval_get(&args);
|
||||
if (retval)
|
||||
return retval;
|
||||
retval = context->put_listent(context,
|
||||
namesp,
|
||||
(char *)name_rmt->name,
|
||||
(int)name_rmt->namelen,
|
||||
valuelen,
|
||||
(char*)args.value);
|
||||
kmem_free(args.value, valuelen);
|
||||
}
|
||||
else {
|
||||
retval = context->put_listent(context,
|
||||
namesp,
|
||||
(char *)name_rmt->name,
|
||||
(int)name_rmt->namelen,
|
||||
valuelen,
|
||||
NULL);
|
||||
}
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
if (retval == 0) {
|
||||
cursor->offset++;
|
||||
}
|
||||
if (context->seen_enough)
|
||||
break;
|
||||
cursor->offset++;
|
||||
}
|
||||
xfs_attr_trace_l_cl("blk end", context, leaf);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
#define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \
|
||||
(((struct attrlist_ent *) 0)->a_name - (char *) 0)
|
||||
#define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \
|
||||
((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
|
||||
& ~(sizeof(u_int32_t)-1))
|
||||
|
||||
/*
|
||||
* Format an attribute and copy it out to the user's buffer.
|
||||
* Take care to check values and protect against them changing later,
|
||||
* we may be reading them directly out of a user buffer.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
STATIC int
|
||||
xfs_attr_put_listent(xfs_attr_list_context_t *context,
|
||||
attrnames_t *namesp, char *name, int namelen, int valuelen)
|
||||
{
|
||||
attrlist_ent_t *aep;
|
||||
int arraytop;
|
||||
|
||||
ASSERT(!(context->flags & ATTR_KERNOVAL));
|
||||
if (context->flags & ATTR_KERNAMELS) {
|
||||
char *offset;
|
||||
|
||||
ASSERT(context->count >= 0);
|
||||
|
||||
arraytop = context->count + namesp->attr_namelen + namelen + 1;
|
||||
if (arraytop > context->firstu) {
|
||||
context->count = -1; /* insufficient space */
|
||||
return(1);
|
||||
}
|
||||
offset = (char *)context->alist + context->count;
|
||||
strncpy(offset, namesp->attr_name, namesp->attr_namelen);
|
||||
offset += namesp->attr_namelen;
|
||||
strncpy(offset, name, namelen); /* real name */
|
||||
offset += namelen;
|
||||
*offset = '\0';
|
||||
context->count += namesp->attr_namelen + namelen + 1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
ASSERT(context->count >= 0);
|
||||
ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
|
||||
ASSERT(context->firstu >= sizeof(*context->alist));
|
||||
ASSERT(context->firstu <= context->bufsize);
|
||||
|
||||
arraytop = sizeof(*context->alist) +
|
||||
context->count * sizeof(context->alist->al_offset[0]);
|
||||
context->firstu -= ATTR_ENTSIZE(namelen);
|
||||
if (context->firstu < arraytop) {
|
||||
xfs_attr_trace_l_c("buffer full", context);
|
||||
context->alist->al_more = 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
aep = (attrlist_ent_t *)&(((char *)context->alist)[ context->firstu ]);
|
||||
aep->a_valuelen = valuelen;
|
||||
memcpy(aep->a_name, name, namelen);
|
||||
aep->a_name[ namelen ] = 0;
|
||||
context->alist->al_offset[ context->count++ ] = context->firstu;
|
||||
context->alist->al_count = context->count;
|
||||
xfs_attr_trace_l_c("add", context);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
* Manage the INCOMPLETE flag in a leaf entry
|
||||
|
@ -129,6 +129,19 @@ typedef struct xfs_attr_leafblock {
|
||||
#define XFS_ATTR_SECURE (1 << XFS_ATTR_SECURE_BIT)
|
||||
#define XFS_ATTR_INCOMPLETE (1 << XFS_ATTR_INCOMPLETE_BIT)
|
||||
|
||||
/*
|
||||
* Conversion macros for converting namespace bits from argument flags
|
||||
* to ondisk flags.
|
||||
*/
|
||||
#define XFS_ATTR_NSP_ARGS_MASK (ATTR_ROOT | ATTR_SECURE)
|
||||
#define XFS_ATTR_NSP_ONDISK_MASK (XFS_ATTR_ROOT | XFS_ATTR_SECURE)
|
||||
#define XFS_ATTR_NSP_ONDISK(flags) ((flags) & XFS_ATTR_NSP_ONDISK_MASK)
|
||||
#define XFS_ATTR_NSP_ARGS(flags) ((flags) & XFS_ATTR_NSP_ARGS_MASK)
|
||||
#define XFS_ATTR_NSP_ARGS_TO_ONDISK(x) (((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\
|
||||
((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0))
|
||||
#define XFS_ATTR_NSP_ONDISK_TO_ARGS(x) (((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\
|
||||
((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0))
|
||||
|
||||
/*
|
||||
* Alignment for namelist and valuelist entries (since they are mixed
|
||||
* there can be only one alignment value)
|
||||
@ -196,16 +209,26 @@ static inline int xfs_attr_leaf_entsize_local_max(int bsize)
|
||||
* Structure used to pass context around among the routines.
|
||||
*========================================================================*/
|
||||
|
||||
|
||||
struct xfs_attr_list_context;
|
||||
|
||||
typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, struct attrnames *,
|
||||
char *, int, int, char *);
|
||||
|
||||
typedef struct xfs_attr_list_context {
|
||||
struct xfs_inode *dp; /* inode */
|
||||
struct attrlist_cursor_kern *cursor;/* position in list */
|
||||
struct attrlist *alist; /* output buffer */
|
||||
int count; /* num used entries */
|
||||
int dupcnt; /* count dup hashvals seen */
|
||||
int bufsize;/* total buffer size */
|
||||
int firstu; /* first used byte in buffer */
|
||||
int flags; /* from VOP call */
|
||||
int resynch;/* T/F: resynch with cursor */
|
||||
struct xfs_inode *dp; /* inode */
|
||||
struct attrlist_cursor_kern *cursor; /* position in list */
|
||||
struct attrlist *alist; /* output buffer */
|
||||
int seen_enough; /* T/F: seen enough of list? */
|
||||
int count; /* num used entries */
|
||||
int dupcnt; /* count dup hashvals seen */
|
||||
int bufsize; /* total buffer size */
|
||||
int firstu; /* first used byte in buffer */
|
||||
int flags; /* from VOP call */
|
||||
int resynch; /* T/F: resynch with cursor */
|
||||
int put_value; /* T/F: need value for listent */
|
||||
put_listent_func_t put_listent; /* list output fmt function */
|
||||
int index; /* index into output buffer */
|
||||
} xfs_attr_list_context_t;
|
||||
|
||||
/*
|
||||
|
@ -109,26 +109,6 @@ bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
|
||||
prev->bd_next = bdp->bd_next; /* remove from after prev */
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for a specific ops vector on the specified behavior chain.
|
||||
* Return the associated behavior descriptor. Or NULL, if not found.
|
||||
*/
|
||||
bhv_desc_t *
|
||||
bhv_lookup(bhv_head_t *bhp, void *ops)
|
||||
{
|
||||
bhv_desc_t *curdesc;
|
||||
|
||||
for (curdesc = bhp->bh_first;
|
||||
curdesc != NULL;
|
||||
curdesc = curdesc->bd_next) {
|
||||
|
||||
if (curdesc->bd_ops == ops)
|
||||
return curdesc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks for the first behavior within a specified range of positions.
|
||||
* Return the associated behavior descriptor. Or NULL, if none found.
|
||||
|
@ -176,12 +176,10 @@ extern void bhv_insert_initial(bhv_head_t *, bhv_desc_t *);
|
||||
* Behavior module prototypes.
|
||||
*/
|
||||
extern void bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp);
|
||||
extern bhv_desc_t * bhv_lookup(bhv_head_t *bhp, void *ops);
|
||||
extern bhv_desc_t * bhv_lookup_range(bhv_head_t *bhp, int low, int high);
|
||||
extern bhv_desc_t * bhv_base(bhv_head_t *bhp);
|
||||
|
||||
/* No bhv locking on Linux */
|
||||
#define bhv_lookup_unlocked bhv_lookup
|
||||
#define bhv_base_unlocked bhv_base
|
||||
|
||||
#endif /* __XFS_BEHAVIOR_H__ */
|
||||
|
@ -2999,7 +2999,7 @@ xfs_bmap_btree_to_extents(
|
||||
int error; /* error return value */
|
||||
xfs_ifork_t *ifp; /* inode fork data */
|
||||
xfs_mount_t *mp; /* mount point structure */
|
||||
xfs_bmbt_ptr_t *pp; /* ptr to block address */
|
||||
__be64 *pp; /* ptr to block address */
|
||||
xfs_bmbt_block_t *rblock;/* root btree block */
|
||||
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
@ -3011,12 +3011,12 @@ xfs_bmap_btree_to_extents(
|
||||
ASSERT(XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes) == 1);
|
||||
mp = ip->i_mount;
|
||||
pp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, ifp->if_broot_bytes);
|
||||
cbno = be64_to_cpu(*pp);
|
||||
*logflagsp = 0;
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), 1)))
|
||||
if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
|
||||
return error;
|
||||
#endif
|
||||
cbno = INT_GET(*pp, ARCH_CONVERT);
|
||||
if ((error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp,
|
||||
XFS_BMAP_BTREE_REF)))
|
||||
return error;
|
||||
@ -3512,9 +3512,9 @@ xfs_bmap_extents_to_btree(
|
||||
*/
|
||||
kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
|
||||
arp = XFS_BMAP_REC_IADDR(ablock, 1, cur);
|
||||
INT_SET(kp->br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(arp));
|
||||
kp->br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(arp));
|
||||
pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
|
||||
INT_SET(*pp, ARCH_CONVERT, args.fsbno);
|
||||
*pp = cpu_to_be64(args.fsbno);
|
||||
/*
|
||||
* Do all this logging at the end so that
|
||||
* the root is at the right level.
|
||||
@ -3705,7 +3705,7 @@ STATIC xfs_bmbt_rec_t * /* pointer to found extent entry */
|
||||
xfs_bmap_search_extents(
|
||||
xfs_inode_t *ip, /* incore inode pointer */
|
||||
xfs_fileoff_t bno, /* block number searched for */
|
||||
int whichfork, /* data or attr fork */
|
||||
int fork, /* data or attr fork */
|
||||
int *eofp, /* out: end of file found */
|
||||
xfs_extnum_t *lastxp, /* out: last extent index */
|
||||
xfs_bmbt_irec_t *gotp, /* out: extent entry found */
|
||||
@ -3713,25 +3713,28 @@ xfs_bmap_search_extents(
|
||||
{
|
||||
xfs_ifork_t *ifp; /* inode fork pointer */
|
||||
xfs_bmbt_rec_t *ep; /* extent record pointer */
|
||||
int rt; /* realtime flag */
|
||||
|
||||
XFS_STATS_INC(xs_look_exlist);
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
ifp = XFS_IFORK_PTR(ip, fork);
|
||||
|
||||
ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp);
|
||||
|
||||
rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip);
|
||||
if (unlikely(!rt && !gotp->br_startblock && (*lastxp != NULLEXTNUM))) {
|
||||
cmn_err(CE_PANIC,"Access to block zero: fs: <%s> inode: %lld "
|
||||
"start_block : %llx start_off : %llx blkcnt : %llx "
|
||||
"extent-state : %x \n",
|
||||
(ip->i_mount)->m_fsname, (long long)ip->i_ino,
|
||||
if (unlikely(!(gotp->br_startblock) && (*lastxp != NULLEXTNUM) &&
|
||||
!(XFS_IS_REALTIME_INODE(ip) && fork == XFS_DATA_FORK))) {
|
||||
xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount,
|
||||
"Access to block zero in inode %llu "
|
||||
"start_block: %llx start_off: %llx "
|
||||
"blkcnt: %llx extent-state: %x lastx: %x\n",
|
||||
(unsigned long long)ip->i_ino,
|
||||
(unsigned long long)gotp->br_startblock,
|
||||
(unsigned long long)gotp->br_startoff,
|
||||
(unsigned long long)gotp->br_blockcount,
|
||||
gotp->br_state);
|
||||
}
|
||||
return ep;
|
||||
gotp->br_state, *lastxp);
|
||||
*lastxp = NULLEXTNUM;
|
||||
*eofp = 1;
|
||||
return NULL;
|
||||
}
|
||||
return ep;
|
||||
}
|
||||
|
||||
|
||||
@ -4494,7 +4497,7 @@ xfs_bmap_read_extents(
|
||||
xfs_ifork_t *ifp; /* fork structure */
|
||||
int level; /* btree level, for checking */
|
||||
xfs_mount_t *mp; /* file system mount structure */
|
||||
xfs_bmbt_ptr_t *pp; /* pointer to block address */
|
||||
__be64 *pp; /* pointer to block address */
|
||||
/* REFERENCED */
|
||||
xfs_extnum_t room; /* number of entries there's room for */
|
||||
|
||||
@ -4510,10 +4513,10 @@ xfs_bmap_read_extents(
|
||||
level = be16_to_cpu(block->bb_level);
|
||||
ASSERT(level > 0);
|
||||
pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
|
||||
ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
|
||||
ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
|
||||
ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
|
||||
bno = INT_GET(*pp, ARCH_CONVERT);
|
||||
bno = be64_to_cpu(*pp);
|
||||
ASSERT(bno != NULLDFSBNO);
|
||||
ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
|
||||
ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
|
||||
/*
|
||||
* Go down the tree until leaf level is reached, following the first
|
||||
* pointer (leftmost) at each level.
|
||||
@ -4530,10 +4533,8 @@ xfs_bmap_read_extents(
|
||||
break;
|
||||
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block,
|
||||
1, mp->m_bmap_dmxr[1]);
|
||||
XFS_WANT_CORRUPTED_GOTO(
|
||||
XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)),
|
||||
error0);
|
||||
bno = INT_GET(*pp, ARCH_CONVERT);
|
||||
bno = be64_to_cpu(*pp);
|
||||
XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
|
||||
xfs_trans_brelse(tp, bp);
|
||||
}
|
||||
/*
|
||||
@ -6141,7 +6142,7 @@ xfs_check_block(
|
||||
short sz)
|
||||
{
|
||||
int i, j, dmxr;
|
||||
xfs_bmbt_ptr_t *pp, *thispa; /* pointer to block address */
|
||||
__be64 *pp, *thispa; /* pointer to block address */
|
||||
xfs_bmbt_key_t *prevp, *keyp;
|
||||
|
||||
ASSERT(be16_to_cpu(block->bb_level) > 0);
|
||||
@ -6179,11 +6180,10 @@ xfs_check_block(
|
||||
thispa = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
|
||||
xfs_bmbt, block, j, dmxr);
|
||||
}
|
||||
if (INT_GET(*thispa, ARCH_CONVERT) ==
|
||||
INT_GET(*pp, ARCH_CONVERT)) {
|
||||
if (*thispa == *pp) {
|
||||
cmn_err(CE_WARN, "%s: thispa(%d) == pp(%d) %Ld",
|
||||
__FUNCTION__, j, i,
|
||||
INT_GET(*thispa, ARCH_CONVERT));
|
||||
(unsigned long long)be64_to_cpu(*thispa));
|
||||
panic("%s: ptrs are equal in node\n",
|
||||
__FUNCTION__);
|
||||
}
|
||||
@ -6210,7 +6210,7 @@ xfs_bmap_check_leaf_extents(
|
||||
xfs_ifork_t *ifp; /* fork structure */
|
||||
int level; /* btree level, for checking */
|
||||
xfs_mount_t *mp; /* file system mount structure */
|
||||
xfs_bmbt_ptr_t *pp; /* pointer to block address */
|
||||
__be64 *pp; /* pointer to block address */
|
||||
xfs_bmbt_rec_t *ep; /* pointer to current extent */
|
||||
xfs_bmbt_rec_t *lastp; /* pointer to previous extent */
|
||||
xfs_bmbt_rec_t *nextp; /* pointer to next extent */
|
||||
@ -6231,10 +6231,12 @@ xfs_bmap_check_leaf_extents(
|
||||
ASSERT(level > 0);
|
||||
xfs_check_block(block, mp, 1, ifp->if_broot_bytes);
|
||||
pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
|
||||
ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
|
||||
ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
|
||||
ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
|
||||
bno = INT_GET(*pp, ARCH_CONVERT);
|
||||
bno = be64_to_cpu(*pp);
|
||||
|
||||
ASSERT(bno != NULLDFSBNO);
|
||||
ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
|
||||
ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
|
||||
|
||||
/*
|
||||
* Go down the tree until leaf level is reached, following the first
|
||||
* pointer (leftmost) at each level.
|
||||
@ -6265,8 +6267,8 @@ xfs_bmap_check_leaf_extents(
|
||||
xfs_check_block(block, mp, 0, 0);
|
||||
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize, xfs_bmbt, block,
|
||||
1, mp->m_bmap_dmxr[1]);
|
||||
XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, INT_GET(*pp, ARCH_CONVERT)), error0);
|
||||
bno = INT_GET(*pp, ARCH_CONVERT);
|
||||
bno = be64_to_cpu(*pp);
|
||||
XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0);
|
||||
if (bp_release) {
|
||||
bp_release = 0;
|
||||
xfs_trans_brelse(NULL, bp);
|
||||
@ -6372,7 +6374,7 @@ xfs_bmap_count_blocks(
|
||||
xfs_ifork_t *ifp; /* fork structure */
|
||||
int level; /* btree level, for checking */
|
||||
xfs_mount_t *mp; /* file system mount structure */
|
||||
xfs_bmbt_ptr_t *pp; /* pointer to block address */
|
||||
__be64 *pp; /* pointer to block address */
|
||||
|
||||
bno = NULLFSBLOCK;
|
||||
mp = ip->i_mount;
|
||||
@ -6395,10 +6397,10 @@ xfs_bmap_count_blocks(
|
||||
level = be16_to_cpu(block->bb_level);
|
||||
ASSERT(level > 0);
|
||||
pp = XFS_BMAP_BROOT_PTR_ADDR(block, 1, ifp->if_broot_bytes);
|
||||
ASSERT(INT_GET(*pp, ARCH_CONVERT) != NULLDFSBNO);
|
||||
ASSERT(XFS_FSB_TO_AGNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agcount);
|
||||
ASSERT(XFS_FSB_TO_AGBNO(mp, INT_GET(*pp, ARCH_CONVERT)) < mp->m_sb.sb_agblocks);
|
||||
bno = INT_GET(*pp, ARCH_CONVERT);
|
||||
bno = be64_to_cpu(*pp);
|
||||
ASSERT(bno != NULLDFSBNO);
|
||||
ASSERT(XFS_FSB_TO_AGNO(mp, bno) < mp->m_sb.sb_agcount);
|
||||
ASSERT(XFS_FSB_TO_AGBNO(mp, bno) < mp->m_sb.sb_agblocks);
|
||||
|
||||
if (unlikely(xfs_bmap_count_tree(mp, tp, ifp, bno, level, count) < 0)) {
|
||||
XFS_ERROR_REPORT("xfs_bmap_count_blocks(2)", XFS_ERRLEVEL_LOW,
|
||||
@ -6425,7 +6427,7 @@ xfs_bmap_count_tree(
|
||||
int error;
|
||||
xfs_buf_t *bp, *nbp;
|
||||
int level = levelin;
|
||||
xfs_bmbt_ptr_t *pp;
|
||||
__be64 *pp;
|
||||
xfs_fsblock_t bno = blockno;
|
||||
xfs_fsblock_t nextbno;
|
||||
xfs_bmbt_block_t *block, *nextblock;
|
||||
@ -6452,7 +6454,7 @@ xfs_bmap_count_tree(
|
||||
/* Dive to the next level */
|
||||
pp = XFS_BTREE_PTR_ADDR(mp->m_sb.sb_blocksize,
|
||||
xfs_bmbt, block, 1, mp->m_bmap_dmxr[1]);
|
||||
bno = INT_GET(*pp, ARCH_CONVERT);
|
||||
bno = be64_to_cpu(*pp);
|
||||
if (unlikely((error =
|
||||
xfs_bmap_count_tree(mp, tp, ifp, bno, level, count)) < 0)) {
|
||||
xfs_trans_brelse(tp, bp);
|
||||
|
@ -58,7 +58,7 @@ STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
|
||||
STATIC int xfs_bmbt_lshift(xfs_btree_cur_t *, int, int *);
|
||||
STATIC int xfs_bmbt_rshift(xfs_btree_cur_t *, int, int *);
|
||||
STATIC int xfs_bmbt_split(xfs_btree_cur_t *, int, xfs_fsblock_t *,
|
||||
xfs_bmbt_key_t *, xfs_btree_cur_t **, int *);
|
||||
__uint64_t *, xfs_btree_cur_t **, int *);
|
||||
STATIC int xfs_bmbt_updkey(xfs_btree_cur_t *, xfs_bmbt_key_t *, int);
|
||||
|
||||
|
||||
@ -192,16 +192,11 @@ xfs_bmbt_trace_argifk(
|
||||
xfs_btree_cur_t *cur,
|
||||
int i,
|
||||
xfs_fsblock_t f,
|
||||
xfs_bmbt_key_t *k,
|
||||
xfs_dfiloff_t o,
|
||||
int line)
|
||||
{
|
||||
xfs_dfsbno_t d;
|
||||
xfs_dfiloff_t o;
|
||||
|
||||
d = (xfs_dfsbno_t)f;
|
||||
o = INT_GET(k->br_startoff, ARCH_CONVERT);
|
||||
xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
|
||||
i, d >> 32, (int)d, o >> 32,
|
||||
i, (xfs_dfsbno_t)f >> 32, (int)f, o >> 32,
|
||||
(int)o, 0, 0, 0,
|
||||
0, 0, 0);
|
||||
}
|
||||
@ -248,7 +243,7 @@ xfs_bmbt_trace_argik(
|
||||
{
|
||||
xfs_dfiloff_t o;
|
||||
|
||||
o = INT_GET(k->br_startoff, ARCH_CONVERT);
|
||||
o = be64_to_cpu(k->br_startoff);
|
||||
xfs_bmbt_trace_enter(func, cur, ARGS, XFS_BMBT_KTRACE_ARGIFK, line,
|
||||
i, o >> 32, (int)o, 0,
|
||||
0, 0, 0, 0,
|
||||
@ -286,8 +281,8 @@ xfs_bmbt_trace_cursor(
|
||||
xfs_bmbt_trace_argfffi(fname, c, o, b, i, j, __LINE__)
|
||||
#define XFS_BMBT_TRACE_ARGI(c,i) \
|
||||
xfs_bmbt_trace_argi(fname, c, i, __LINE__)
|
||||
#define XFS_BMBT_TRACE_ARGIFK(c,i,f,k) \
|
||||
xfs_bmbt_trace_argifk(fname, c, i, f, k, __LINE__)
|
||||
#define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) \
|
||||
xfs_bmbt_trace_argifk(fname, c, i, f, s, __LINE__)
|
||||
#define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \
|
||||
xfs_bmbt_trace_argifr(fname, c, i, f, r, __LINE__)
|
||||
#define XFS_BMBT_TRACE_ARGIK(c,i,k) \
|
||||
@ -299,7 +294,7 @@ xfs_bmbt_trace_cursor(
|
||||
#define XFS_BMBT_TRACE_ARGBII(c,b,i,j)
|
||||
#define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j)
|
||||
#define XFS_BMBT_TRACE_ARGI(c,i)
|
||||
#define XFS_BMBT_TRACE_ARGIFK(c,i,f,k)
|
||||
#define XFS_BMBT_TRACE_ARGIFK(c,i,f,s)
|
||||
#define XFS_BMBT_TRACE_ARGIFR(c,i,f,r)
|
||||
#define XFS_BMBT_TRACE_ARGIK(c,i,k)
|
||||
#define XFS_BMBT_TRACE_CURSOR(c,s)
|
||||
@ -357,7 +352,7 @@ xfs_bmbt_delrec(
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
|
||||
XFS_BMBT_TRACE_ARGI(cur, level);
|
||||
ptr = cur->bc_ptrs[level];
|
||||
tcur = (xfs_btree_cur_t *)0;
|
||||
tcur = NULL;
|
||||
if (ptr == 0) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
|
||||
*stat = 0;
|
||||
@ -382,7 +377,7 @@ xfs_bmbt_delrec(
|
||||
pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = ptr; i < numrecs; i++) {
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) {
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
goto error0;
|
||||
}
|
||||
@ -404,7 +399,8 @@ xfs_bmbt_delrec(
|
||||
xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1);
|
||||
}
|
||||
if (ptr == 1) {
|
||||
INT_SET(key.br_startoff, ARCH_CONVERT, xfs_bmbt_disk_get_startoff(rp));
|
||||
key.br_startoff =
|
||||
cpu_to_be64(xfs_bmbt_disk_get_startoff(rp));
|
||||
kp = &key;
|
||||
}
|
||||
}
|
||||
@ -621,7 +617,7 @@ xfs_bmbt_delrec(
|
||||
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < numrrecs; i++) {
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) {
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
goto error0;
|
||||
}
|
||||
@ -748,7 +744,7 @@ xfs_bmbt_insrec(
|
||||
int logflags; /* inode logging flags */
|
||||
xfs_fsblock_t nbno; /* new block number */
|
||||
struct xfs_btree_cur *ncur; /* new btree cursor */
|
||||
xfs_bmbt_key_t nkey; /* new btree key value */
|
||||
__uint64_t startoff; /* new btree key value */
|
||||
xfs_bmbt_rec_t nrec; /* new record count */
|
||||
int optr; /* old key/record index */
|
||||
xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
|
||||
@ -759,9 +755,8 @@ xfs_bmbt_insrec(
|
||||
ASSERT(level < cur->bc_nlevels);
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
|
||||
XFS_BMBT_TRACE_ARGIFR(cur, level, *bnop, recp);
|
||||
ncur = (xfs_btree_cur_t *)0;
|
||||
INT_SET(key.br_startoff, ARCH_CONVERT,
|
||||
xfs_bmbt_disk_get_startoff(recp));
|
||||
ncur = NULL;
|
||||
key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(recp));
|
||||
optr = ptr = cur->bc_ptrs[level];
|
||||
if (ptr == 0) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
|
||||
@ -820,7 +815,7 @@ xfs_bmbt_insrec(
|
||||
optr = ptr = cur->bc_ptrs[level];
|
||||
} else {
|
||||
if ((error = xfs_bmbt_split(cur, level,
|
||||
&nbno, &nkey, &ncur,
|
||||
&nbno, &startoff, &ncur,
|
||||
&i))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur,
|
||||
ERROR);
|
||||
@ -840,7 +835,7 @@ xfs_bmbt_insrec(
|
||||
#endif
|
||||
ptr = cur->bc_ptrs[level];
|
||||
xfs_bmbt_disk_set_allf(&nrec,
|
||||
nkey.br_startoff, 0, 0,
|
||||
startoff, 0, 0,
|
||||
XFS_EXT_NORM);
|
||||
} else {
|
||||
XFS_BMBT_TRACE_CURSOR(cur,
|
||||
@ -858,7 +853,7 @@ xfs_bmbt_insrec(
|
||||
pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = numrecs; i >= ptr; i--) {
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i - 1], ARCH_CONVERT),
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, pp[i - 1],
|
||||
level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
@ -870,14 +865,13 @@ xfs_bmbt_insrec(
|
||||
memmove(&pp[ptr], &pp[ptr - 1], /* INT_: direct copy */
|
||||
(numrecs - ptr + 1) * sizeof(*pp));
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)*bnop,
|
||||
level))) {
|
||||
if ((error = xfs_btree_check_lptr(cur, *bnop, level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
kp[ptr - 1] = key;
|
||||
INT_SET(pp[ptr - 1], ARCH_CONVERT, *bnop);
|
||||
pp[ptr - 1] = cpu_to_be64(*bnop);
|
||||
numrecs++;
|
||||
block->bb_numrecs = cpu_to_be16(numrecs);
|
||||
xfs_bmbt_log_keys(cur, bp, ptr, numrecs);
|
||||
@ -988,7 +982,7 @@ xfs_bmbt_killroot(
|
||||
cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(cpp[i], ARCH_CONVERT), level - 1))) {
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, cpp[i], level - 1))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
@ -1132,7 +1126,7 @@ xfs_bmbt_lookup(
|
||||
d = XFS_FSB_TO_DADDR(mp, fsbno);
|
||||
bp = cur->bc_bufs[level];
|
||||
if (bp && XFS_BUF_ADDR(bp) != d)
|
||||
bp = (xfs_buf_t *)0;
|
||||
bp = NULL;
|
||||
if (!bp) {
|
||||
if ((error = xfs_btree_read_bufl(mp, tp, fsbno,
|
||||
0, &bp, XFS_BMAP_BTREE_REF))) {
|
||||
@ -1170,7 +1164,7 @@ xfs_bmbt_lookup(
|
||||
keyno = (low + high) >> 1;
|
||||
if (level > 0) {
|
||||
kkp = kkbase + keyno - 1;
|
||||
startoff = INT_GET(kkp->br_startoff, ARCH_CONVERT);
|
||||
startoff = be64_to_cpu(kkp->br_startoff);
|
||||
} else {
|
||||
krp = krbase + keyno - 1;
|
||||
startoff = xfs_bmbt_disk_get_startoff(krp);
|
||||
@ -1189,13 +1183,13 @@ xfs_bmbt_lookup(
|
||||
if (diff > 0 && --keyno < 1)
|
||||
keyno = 1;
|
||||
pp = XFS_BMAP_PTR_IADDR(block, keyno, cur);
|
||||
fsbno = be64_to_cpu(*pp);
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
|
||||
if ((error = xfs_btree_check_lptr(cur, fsbno, level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
fsbno = INT_GET(*pp, ARCH_CONVERT);
|
||||
cur->bc_ptrs[level] = keyno;
|
||||
}
|
||||
}
|
||||
@ -1313,7 +1307,7 @@ xfs_bmbt_lshift(
|
||||
lpp = XFS_BMAP_PTR_IADDR(left, lrecs, cur);
|
||||
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(*rpp, ARCH_CONVERT), level))) {
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, *rpp, level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
@ -1340,7 +1334,7 @@ xfs_bmbt_lshift(
|
||||
if (level > 0) {
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < rrecs; i++) {
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i + 1], ARCH_CONVERT),
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, rpp[i + 1],
|
||||
level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
@ -1354,8 +1348,7 @@ xfs_bmbt_lshift(
|
||||
} else {
|
||||
memmove(rrp, rrp + 1, rrecs * sizeof(*rrp));
|
||||
xfs_bmbt_log_recs(cur, rbp, 1, rrecs);
|
||||
INT_SET(key.br_startoff, ARCH_CONVERT,
|
||||
xfs_bmbt_disk_get_startoff(rrp));
|
||||
key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
|
||||
rkp = &key;
|
||||
}
|
||||
if ((error = xfs_bmbt_updkey(cur, rkp, level + 1))) {
|
||||
@ -1445,7 +1438,7 @@ xfs_bmbt_rshift(
|
||||
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = be16_to_cpu(right->bb_numrecs) - 1; i >= 0; i--) {
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(rpp[i], ARCH_CONVERT), level))) {
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
@ -1454,7 +1447,7 @@ xfs_bmbt_rshift(
|
||||
memmove(rkp + 1, rkp, be16_to_cpu(right->bb_numrecs) * sizeof(*rkp));
|
||||
memmove(rpp + 1, rpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(*lpp, ARCH_CONVERT), level))) {
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, *lpp, level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
@ -1469,8 +1462,7 @@ xfs_bmbt_rshift(
|
||||
memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
|
||||
*rrp = *lrp;
|
||||
xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
|
||||
INT_SET(key.br_startoff, ARCH_CONVERT,
|
||||
xfs_bmbt_disk_get_startoff(rrp));
|
||||
key.br_startoff = cpu_to_be64(xfs_bmbt_disk_get_startoff(rrp));
|
||||
rkp = &key;
|
||||
}
|
||||
be16_add(&left->bb_numrecs, -1);
|
||||
@ -1535,7 +1527,7 @@ xfs_bmbt_split(
|
||||
xfs_btree_cur_t *cur,
|
||||
int level,
|
||||
xfs_fsblock_t *bnop,
|
||||
xfs_bmbt_key_t *keyp,
|
||||
__uint64_t *startoff,
|
||||
xfs_btree_cur_t **curp,
|
||||
int *stat) /* success/failure */
|
||||
{
|
||||
@ -1560,7 +1552,7 @@ xfs_bmbt_split(
|
||||
xfs_bmbt_rec_t *rrp; /* right record pointer */
|
||||
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
|
||||
XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, keyp);
|
||||
XFS_BMBT_TRACE_ARGIFK(cur, level, *bnop, *startoff);
|
||||
args.tp = cur->bc_tp;
|
||||
args.mp = cur->bc_mp;
|
||||
lbp = cur->bc_bufs[level];
|
||||
@ -1619,7 +1611,7 @@ xfs_bmbt_split(
|
||||
rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < be16_to_cpu(right->bb_numrecs); i++) {
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(lpp[i], ARCH_CONVERT), level))) {
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, lpp[i], level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
@ -1629,13 +1621,13 @@ xfs_bmbt_split(
|
||||
memcpy(rpp, lpp, be16_to_cpu(right->bb_numrecs) * sizeof(*rpp));
|
||||
xfs_bmbt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
|
||||
xfs_bmbt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
|
||||
keyp->br_startoff = INT_GET(rkp->br_startoff, ARCH_CONVERT);
|
||||
*startoff = be64_to_cpu(rkp->br_startoff);
|
||||
} else {
|
||||
lrp = XFS_BMAP_REC_IADDR(left, i, cur);
|
||||
rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
|
||||
memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
|
||||
xfs_bmbt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
|
||||
keyp->br_startoff = xfs_bmbt_disk_get_startoff(rrp);
|
||||
*startoff = xfs_bmbt_disk_get_startoff(rrp);
|
||||
}
|
||||
be16_add(&left->bb_numrecs, -(be16_to_cpu(right->bb_numrecs)));
|
||||
right->bb_rightsib = left->bb_rightsib;
|
||||
@ -1728,9 +1720,9 @@ xfs_bmdr_to_bmbt(
|
||||
{
|
||||
int dmxr;
|
||||
xfs_bmbt_key_t *fkp;
|
||||
xfs_bmbt_ptr_t *fpp;
|
||||
__be64 *fpp;
|
||||
xfs_bmbt_key_t *tkp;
|
||||
xfs_bmbt_ptr_t *tpp;
|
||||
__be64 *tpp;
|
||||
|
||||
rblock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
|
||||
rblock->bb_level = dblock->bb_level;
|
||||
@ -1745,7 +1737,7 @@ xfs_bmdr_to_bmbt(
|
||||
tpp = XFS_BMAP_BROOT_PTR_ADDR(rblock, 1, rblocklen);
|
||||
dmxr = be16_to_cpu(dblock->bb_numrecs);
|
||||
memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
|
||||
memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
|
||||
memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1805,7 +1797,7 @@ xfs_bmbt_decrement(
|
||||
tp = cur->bc_tp;
|
||||
mp = cur->bc_mp;
|
||||
for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
|
||||
fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
|
||||
fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));
|
||||
if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
|
||||
XFS_BMAP_BTREE_REF))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
@ -2135,7 +2127,7 @@ xfs_bmbt_increment(
|
||||
tp = cur->bc_tp;
|
||||
mp = cur->bc_mp;
|
||||
for (block = xfs_bmbt_get_block(cur, lev, &bp); lev > level; ) {
|
||||
fsbno = INT_GET(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur), ARCH_CONVERT);
|
||||
fsbno = be64_to_cpu(*XFS_BMAP_PTR_IADDR(block, cur->bc_ptrs[lev], cur));
|
||||
if ((error = xfs_btree_read_bufl(mp, tp, fsbno, 0, &bp,
|
||||
XFS_BMAP_BTREE_REF))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
@ -2178,7 +2170,7 @@ xfs_bmbt_insert(
|
||||
level = 0;
|
||||
nbno = NULLFSBLOCK;
|
||||
xfs_bmbt_disk_set_all(&nrec, &cur->bc_rec.b);
|
||||
ncur = (xfs_btree_cur_t *)0;
|
||||
ncur = NULL;
|
||||
pcur = cur;
|
||||
do {
|
||||
if ((error = xfs_bmbt_insrec(pcur, level++, &nbno, &nrec, &ncur,
|
||||
@ -2205,7 +2197,7 @@ xfs_bmbt_insert(
|
||||
}
|
||||
if (ncur) {
|
||||
pcur = ncur;
|
||||
ncur = (xfs_btree_cur_t *)0;
|
||||
ncur = NULL;
|
||||
}
|
||||
} while (nbno != NULLFSBLOCK);
|
||||
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
|
||||
@ -2356,12 +2348,12 @@ xfs_bmbt_newroot(
|
||||
args.firstblock = args.fsbno;
|
||||
if (args.fsbno == NULLFSBLOCK) {
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(*pp, ARCH_CONVERT), level))) {
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
args.fsbno = INT_GET(*pp, ARCH_CONVERT);
|
||||
args.fsbno = be64_to_cpu(*pp);
|
||||
args.type = XFS_ALLOCTYPE_START_BNO;
|
||||
} else
|
||||
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
@ -2393,7 +2385,7 @@ xfs_bmbt_newroot(
|
||||
cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur);
|
||||
#ifdef DEBUG
|
||||
for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
|
||||
if ((error = xfs_btree_check_lptr(cur, INT_GET(pp[i], ARCH_CONVERT), level))) {
|
||||
if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
@ -2401,13 +2393,12 @@ xfs_bmbt_newroot(
|
||||
#endif
|
||||
memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp));
|
||||
#ifdef DEBUG
|
||||
if ((error = xfs_btree_check_lptr(cur, (xfs_bmbt_ptr_t)args.fsbno,
|
||||
level))) {
|
||||
if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
INT_SET(*pp, ARCH_CONVERT, args.fsbno);
|
||||
*pp = cpu_to_be64(args.fsbno);
|
||||
xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs),
|
||||
cur->bc_private.b.whichfork);
|
||||
xfs_btree_setbuf(cur, level, bp);
|
||||
@ -2681,9 +2672,9 @@ xfs_bmbt_to_bmdr(
|
||||
{
|
||||
int dmxr;
|
||||
xfs_bmbt_key_t *fkp;
|
||||
xfs_bmbt_ptr_t *fpp;
|
||||
__be64 *fpp;
|
||||
xfs_bmbt_key_t *tkp;
|
||||
xfs_bmbt_ptr_t *tpp;
|
||||
__be64 *tpp;
|
||||
|
||||
ASSERT(be32_to_cpu(rblock->bb_magic) == XFS_BMAP_MAGIC);
|
||||
ASSERT(be64_to_cpu(rblock->bb_leftsib) == NULLDFSBNO);
|
||||
@ -2698,7 +2689,7 @@ xfs_bmbt_to_bmdr(
|
||||
tpp = XFS_BTREE_PTR_ADDR(dblocklen, xfs_bmdr, dblock, 1, dmxr);
|
||||
dmxr = be16_to_cpu(dblock->bb_numrecs);
|
||||
memcpy(tkp, fkp, sizeof(*fkp) * dmxr);
|
||||
memcpy(tpp, fpp, sizeof(*fpp) * dmxr); /* INT_: direct copy */
|
||||
memcpy(tpp, fpp, sizeof(*fpp) * dmxr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2740,7 +2731,7 @@ xfs_bmbt_update(
|
||||
XFS_BMBT_TRACE_CURSOR(cur, EXIT);
|
||||
return 0;
|
||||
}
|
||||
INT_SET(key.br_startoff, ARCH_CONVERT, off);
|
||||
key.br_startoff = cpu_to_be64(off);
|
||||
if ((error = xfs_bmbt_updkey(cur, &key, 1))) {
|
||||
XFS_BMBT_TRACE_CURSOR(cur, ERROR);
|
||||
return error;
|
||||
|
@ -163,13 +163,14 @@ typedef struct xfs_bmbt_irec
|
||||
/*
|
||||
* Key structure for non-leaf levels of the tree.
|
||||
*/
|
||||
typedef struct xfs_bmbt_key
|
||||
{
|
||||
xfs_dfiloff_t br_startoff; /* starting file offset */
|
||||
typedef struct xfs_bmbt_key {
|
||||
__be64 br_startoff; /* starting file offset */
|
||||
} xfs_bmbt_key_t, xfs_bmdr_key_t;
|
||||
|
||||
typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; /* btree pointer type */
|
||||
/* btree block header type */
|
||||
/* btree pointer type */
|
||||
typedef __be64 xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;
|
||||
|
||||
/* btree block header type */
|
||||
typedef struct xfs_btree_lblock xfs_bmbt_block_t;
|
||||
|
||||
#define XFS_BUF_TO_BMBT_BLOCK(bp) ((xfs_bmbt_block_t *)XFS_BUF_PTR(bp))
|
||||
|
@ -161,7 +161,7 @@ xfs_btree_check_key(
|
||||
|
||||
k1 = ak1;
|
||||
k2 = ak2;
|
||||
ASSERT(INT_GET(k1->br_startoff, ARCH_CONVERT) < INT_GET(k2->br_startoff, ARCH_CONVERT));
|
||||
ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff));
|
||||
break;
|
||||
}
|
||||
case XFS_BTNUM_INO: {
|
||||
@ -170,7 +170,7 @@ xfs_btree_check_key(
|
||||
|
||||
k1 = ak1;
|
||||
k2 = ak2;
|
||||
ASSERT(INT_GET(k1->ir_startino, ARCH_CONVERT) < INT_GET(k2->ir_startino, ARCH_CONVERT));
|
||||
ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -285,8 +285,8 @@ xfs_btree_check_rec(
|
||||
|
||||
r1 = ar1;
|
||||
r2 = ar2;
|
||||
ASSERT(INT_GET(r1->ir_startino, ARCH_CONVERT) + XFS_INODES_PER_CHUNK <=
|
||||
INT_GET(r2->ir_startino, ARCH_CONVERT));
|
||||
ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <=
|
||||
be32_to_cpu(r2->ir_startino));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -145,7 +145,7 @@ typedef struct xfs_btree_cur
|
||||
union {
|
||||
xfs_alloc_rec_incore_t a;
|
||||
xfs_bmbt_irec_t b;
|
||||
xfs_inobt_rec_t i;
|
||||
xfs_inobt_rec_incore_t i;
|
||||
} bc_rec; /* current insert/search record value */
|
||||
struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */
|
||||
int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */
|
||||
@ -243,6 +243,9 @@ xfs_btree_check_lptr(
|
||||
xfs_dfsbno_t ptr, /* btree block disk address */
|
||||
int level); /* btree block level */
|
||||
|
||||
#define xfs_btree_check_lptr_disk(cur, ptr, level) \
|
||||
xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level)
|
||||
|
||||
/*
|
||||
* Checking routine: check that short form block header is ok.
|
||||
*/
|
||||
|
@ -234,7 +234,6 @@ xfs_buf_item_format(
|
||||
ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
|
||||
(bip->bli_flags & XFS_BLI_STALE));
|
||||
bp = bip->bli_buf;
|
||||
ASSERT(XFS_BUF_BP_ISMAPPED(bp));
|
||||
vecp = log_vector;
|
||||
|
||||
/*
|
||||
@ -627,25 +626,6 @@ xfs_buf_item_committed(
|
||||
return (lsn);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called when the transaction holding the buffer is aborted.
|
||||
* Just behave as if the transaction had been cancelled. If we're shutting down
|
||||
* and have aborted this transaction, we'll trap this buffer when it tries to
|
||||
* get written out.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_buf_item_abort(
|
||||
xfs_buf_log_item_t *bip)
|
||||
{
|
||||
xfs_buf_t *bp;
|
||||
|
||||
bp = bip->bli_buf;
|
||||
xfs_buftrace("XFS_ABORT", bp);
|
||||
XFS_BUF_SUPER_STALE(bp);
|
||||
xfs_buf_item_unlock(bip);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called to asynchronously write the buffer associated with this
|
||||
* buf log item out to disk. The buffer will already have been locked by
|
||||
@ -693,7 +673,6 @@ STATIC struct xfs_item_ops xfs_buf_item_ops = {
|
||||
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_buf_item_committed,
|
||||
.iop_push = (void(*)(xfs_log_item_t*))xfs_buf_item_push,
|
||||
.iop_abort = (void(*)(xfs_log_item_t*))xfs_buf_item_abort,
|
||||
.iop_pushbuf = NULL,
|
||||
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_buf_item_committing
|
||||
@ -901,7 +880,6 @@ xfs_buf_item_relse(
|
||||
XFS_BUF_SET_FSPRIVATE(bp, bip->bli_item.li_bio_list);
|
||||
if ((XFS_BUF_FSPRIVATE(bp, void *) == NULL) &&
|
||||
(XFS_BUF_IODONE_FUNC(bp) != NULL)) {
|
||||
ASSERT((XFS_BUF_ISUNINITIAL(bp)) == 0);
|
||||
XFS_BUF_CLR_IODONE_FUNC(bp);
|
||||
}
|
||||
|
||||
|
@ -1054,7 +1054,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
||||
xfs_da_node_entry_t *btree;
|
||||
xfs_dablk_t blkno;
|
||||
int probe, span, max, error, retval;
|
||||
xfs_dahash_t hashval;
|
||||
xfs_dahash_t hashval, btreehashval;
|
||||
xfs_da_args_t *args;
|
||||
|
||||
args = state->args;
|
||||
@ -1079,30 +1079,32 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
||||
return(error);
|
||||
}
|
||||
curr = blk->bp->data;
|
||||
ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC ||
|
||||
be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC ||
|
||||
be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC);
|
||||
blk->magic = be16_to_cpu(curr->magic);
|
||||
ASSERT(blk->magic == XFS_DA_NODE_MAGIC ||
|
||||
blk->magic == XFS_DIR2_LEAFN_MAGIC ||
|
||||
blk->magic == XFS_ATTR_LEAF_MAGIC);
|
||||
|
||||
/*
|
||||
* Search an intermediate node for a match.
|
||||
*/
|
||||
blk->magic = be16_to_cpu(curr->magic);
|
||||
if (blk->magic == XFS_DA_NODE_MAGIC) {
|
||||
node = blk->bp->data;
|
||||
blk->hashval = be32_to_cpu(node->btree[be16_to_cpu(node->hdr.count)-1].hashval);
|
||||
max = be16_to_cpu(node->hdr.count);
|
||||
btreehashval = node->btree[max-1].hashval;
|
||||
blk->hashval = be32_to_cpu(btreehashval);
|
||||
|
||||
/*
|
||||
* Binary search. (note: small blocks will skip loop)
|
||||
*/
|
||||
max = be16_to_cpu(node->hdr.count);
|
||||
probe = span = max / 2;
|
||||
hashval = args->hashval;
|
||||
for (btree = &node->btree[probe]; span > 4;
|
||||
btree = &node->btree[probe]) {
|
||||
span /= 2;
|
||||
if (be32_to_cpu(btree->hashval) < hashval)
|
||||
btreehashval = be32_to_cpu(btree->hashval);
|
||||
if (btreehashval < hashval)
|
||||
probe += span;
|
||||
else if (be32_to_cpu(btree->hashval) > hashval)
|
||||
else if (btreehashval > hashval)
|
||||
probe -= span;
|
||||
else
|
||||
break;
|
||||
@ -1133,10 +1135,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
||||
blk->index = probe;
|
||||
blkno = be32_to_cpu(btree->before);
|
||||
}
|
||||
} else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) {
|
||||
} else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
|
||||
blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL);
|
||||
break;
|
||||
} else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) {
|
||||
} else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
|
||||
blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL);
|
||||
break;
|
||||
}
|
||||
@ -1152,11 +1154,13 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
||||
if (blk->magic == XFS_DIR2_LEAFN_MAGIC) {
|
||||
retval = xfs_dir2_leafn_lookup_int(blk->bp, args,
|
||||
&blk->index, state);
|
||||
}
|
||||
else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
|
||||
} else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
|
||||
retval = xfs_attr_leaf_lookup_int(blk->bp, args);
|
||||
blk->index = args->index;
|
||||
args->blkno = blk->blkno;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
if (((retval == ENOENT) || (retval == ENOATTR)) &&
|
||||
(blk->hashval == args->hashval)) {
|
||||
@ -1166,8 +1170,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result)
|
||||
return(error);
|
||||
if (retval == 0) {
|
||||
continue;
|
||||
}
|
||||
else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
|
||||
} else if (blk->magic == XFS_ATTR_LEAF_MAGIC) {
|
||||
/* path_shift() gives ENOENT */
|
||||
retval = XFS_ERROR(ENOATTR);
|
||||
}
|
||||
|
@ -18,14 +18,6 @@
|
||||
#ifndef __XFS_ERROR_H__
|
||||
#define __XFS_ERROR_H__
|
||||
|
||||
#define XFS_ERECOVER 1 /* Failure to recover log */
|
||||
#define XFS_ELOGSTAT 2 /* Failure to stat log in user space */
|
||||
#define XFS_ENOLOGSPACE 3 /* Reservation too large */
|
||||
#define XFS_ENOTSUP 4 /* Operation not supported */
|
||||
#define XFS_ENOLSN 5 /* Can't find the lsn you asked for */
|
||||
#define XFS_ENOTFOUND 6
|
||||
#define XFS_ENOTXFS 7 /* Not XFS filesystem */
|
||||
|
||||
#ifdef DEBUG
|
||||
#define XFS_ERROR_NTRAP 10
|
||||
extern int xfs_etrap[XFS_ERROR_NTRAP];
|
||||
@ -175,6 +167,7 @@ extern int xfs_errortag_clearall_umount(int64_t fsid, char *fsname, int loud);
|
||||
#define XFS_PTAG_SHUTDOWN_CORRUPT 0x00000010
|
||||
#define XFS_PTAG_SHUTDOWN_IOERROR 0x00000020
|
||||
#define XFS_PTAG_SHUTDOWN_LOGERROR 0x00000040
|
||||
#define XFS_PTAG_FSBLOCK_ZERO 0x00000080
|
||||
|
||||
struct xfs_mount;
|
||||
/* PRINTFLIKE4 */
|
||||
|
@ -33,9 +33,6 @@ kmem_zone_t *xfs_efi_zone;
|
||||
kmem_zone_t *xfs_efd_zone;
|
||||
|
||||
STATIC void xfs_efi_item_unlock(xfs_efi_log_item_t *);
|
||||
STATIC void xfs_efi_item_abort(xfs_efi_log_item_t *);
|
||||
STATIC void xfs_efd_item_abort(xfs_efd_log_item_t *);
|
||||
|
||||
|
||||
void
|
||||
xfs_efi_item_free(xfs_efi_log_item_t *efip)
|
||||
@ -184,7 +181,7 @@ STATIC void
|
||||
xfs_efi_item_unlock(xfs_efi_log_item_t *efip)
|
||||
{
|
||||
if (efip->efi_item.li_flags & XFS_LI_ABORTED)
|
||||
xfs_efi_item_abort(efip);
|
||||
xfs_efi_item_free(efip);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -201,18 +198,6 @@ xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
|
||||
return lsn;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called when the transaction logging the EFI is aborted.
|
||||
* Free up the EFI and return. No need to clean up the slot for
|
||||
* the item in the transaction. That was done by the unpin code
|
||||
* which is called prior to this routine in the abort/fs-shutdown path.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_efi_item_abort(xfs_efi_log_item_t *efip)
|
||||
{
|
||||
xfs_efi_item_free(efip);
|
||||
}
|
||||
|
||||
/*
|
||||
* There isn't much you can do to push on an efi item. It is simply
|
||||
* stuck waiting for all of its corresponding efd items to be
|
||||
@ -255,7 +240,6 @@ STATIC struct xfs_item_ops xfs_efi_item_ops = {
|
||||
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_efi_item_committed,
|
||||
.iop_push = (void(*)(xfs_log_item_t*))xfs_efi_item_push,
|
||||
.iop_abort = (void(*)(xfs_log_item_t*))xfs_efi_item_abort,
|
||||
.iop_pushbuf = NULL,
|
||||
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_efi_item_committing
|
||||
@ -386,33 +370,6 @@ xfs_efi_release(xfs_efi_log_item_t *efip,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called when the transaction that should be committing the
|
||||
* EFD corresponding to the given EFI is aborted. The committed and
|
||||
* canceled flags are used to coordinate the freeing of the EFI and
|
||||
* the references by the transaction that committed it.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_efi_cancel(
|
||||
xfs_efi_log_item_t *efip)
|
||||
{
|
||||
xfs_mount_t *mp;
|
||||
SPLDECL(s);
|
||||
|
||||
mp = efip->efi_item.li_mountp;
|
||||
AIL_LOCK(mp, s);
|
||||
if (efip->efi_flags & XFS_EFI_COMMITTED) {
|
||||
/*
|
||||
* xfs_trans_delete_ail() drops the AIL lock.
|
||||
*/
|
||||
xfs_trans_delete_ail(mp, (xfs_log_item_t *)efip, s);
|
||||
xfs_efi_item_free(efip);
|
||||
} else {
|
||||
efip->efi_flags |= XFS_EFI_CANCELED;
|
||||
AIL_UNLOCK(mp, s);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void
|
||||
xfs_efd_item_free(xfs_efd_log_item_t *efdp)
|
||||
{
|
||||
@ -514,7 +471,7 @@ STATIC void
|
||||
xfs_efd_item_unlock(xfs_efd_log_item_t *efdp)
|
||||
{
|
||||
if (efdp->efd_item.li_flags & XFS_LI_ABORTED)
|
||||
xfs_efd_item_abort(efdp);
|
||||
xfs_efd_item_free(efdp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -540,27 +497,6 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
|
||||
return (xfs_lsn_t)-1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The transaction of which this EFD is a part has been aborted.
|
||||
* Inform its companion EFI of this fact and then clean up after
|
||||
* ourselves. No need to clean up the slot for the item in the
|
||||
* transaction. That was done by the unpin code which is called
|
||||
* prior to this routine in the abort/fs-shutdown path.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_efd_item_abort(xfs_efd_log_item_t *efdp)
|
||||
{
|
||||
/*
|
||||
* If we got a log I/O error, it's always the case that the LR with the
|
||||
* EFI got unpinned and freed before the EFD got aborted. So don't
|
||||
* reference the EFI at all in that case.
|
||||
*/
|
||||
if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
|
||||
xfs_efi_cancel(efdp->efd_efip);
|
||||
|
||||
xfs_efd_item_free(efdp);
|
||||
}
|
||||
|
||||
/*
|
||||
* There isn't much you can do to push on an efd item. It is simply
|
||||
* stuck waiting for the log to be flushed to disk.
|
||||
@ -602,7 +538,6 @@ STATIC struct xfs_item_ops xfs_efd_item_ops = {
|
||||
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_efd_item_committed,
|
||||
.iop_push = (void(*)(xfs_log_item_t*))xfs_efd_item_push,
|
||||
.iop_abort = (void(*)(xfs_log_item_t*))xfs_efd_item_abort,
|
||||
.iop_pushbuf = NULL,
|
||||
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_efd_item_committing
|
||||
|
@ -33,14 +33,16 @@ typedef struct xfs_extent {
|
||||
* conversion routine.
|
||||
*/
|
||||
|
||||
#ifndef HAVE_FORMAT32
|
||||
typedef struct xfs_extent_32 {
|
||||
xfs_dfsbno_t ext_start;
|
||||
xfs_extlen_t ext_len;
|
||||
__uint64_t ext_start;
|
||||
__uint32_t ext_len;
|
||||
} __attribute__((packed)) xfs_extent_32_t;
|
||||
#endif
|
||||
|
||||
typedef struct xfs_extent_64 {
|
||||
xfs_dfsbno_t ext_start;
|
||||
xfs_extlen_t ext_len;
|
||||
__uint64_t ext_start;
|
||||
__uint32_t ext_len;
|
||||
__uint32_t ext_pad;
|
||||
} xfs_extent_64_t;
|
||||
|
||||
@ -50,25 +52,27 @@ typedef struct xfs_extent_64 {
|
||||
* size is given by efi_nextents.
|
||||
*/
|
||||
typedef struct xfs_efi_log_format {
|
||||
unsigned short efi_type; /* efi log item type */
|
||||
unsigned short efi_size; /* size of this item */
|
||||
uint efi_nextents; /* # extents to free */
|
||||
__uint16_t efi_type; /* efi log item type */
|
||||
__uint16_t efi_size; /* size of this item */
|
||||
__uint32_t efi_nextents; /* # extents to free */
|
||||
__uint64_t efi_id; /* efi identifier */
|
||||
xfs_extent_t efi_extents[1]; /* array of extents to free */
|
||||
} xfs_efi_log_format_t;
|
||||
|
||||
#ifndef HAVE_FORMAT32
|
||||
typedef struct xfs_efi_log_format_32 {
|
||||
unsigned short efi_type; /* efi log item type */
|
||||
unsigned short efi_size; /* size of this item */
|
||||
uint efi_nextents; /* # extents to free */
|
||||
__uint16_t efi_type; /* efi log item type */
|
||||
__uint16_t efi_size; /* size of this item */
|
||||
__uint32_t efi_nextents; /* # extents to free */
|
||||
__uint64_t efi_id; /* efi identifier */
|
||||
xfs_extent_32_t efi_extents[1]; /* array of extents to free */
|
||||
} __attribute__((packed)) xfs_efi_log_format_32_t;
|
||||
#endif
|
||||
|
||||
typedef struct xfs_efi_log_format_64 {
|
||||
unsigned short efi_type; /* efi log item type */
|
||||
unsigned short efi_size; /* size of this item */
|
||||
uint efi_nextents; /* # extents to free */
|
||||
__uint16_t efi_type; /* efi log item type */
|
||||
__uint16_t efi_size; /* size of this item */
|
||||
__uint32_t efi_nextents; /* # extents to free */
|
||||
__uint64_t efi_id; /* efi identifier */
|
||||
xfs_extent_64_t efi_extents[1]; /* array of extents to free */
|
||||
} xfs_efi_log_format_64_t;
|
||||
@ -79,25 +83,27 @@ typedef struct xfs_efi_log_format_64 {
|
||||
* size is given by efd_nextents;
|
||||
*/
|
||||
typedef struct xfs_efd_log_format {
|
||||
unsigned short efd_type; /* efd log item type */
|
||||
unsigned short efd_size; /* size of this item */
|
||||
uint efd_nextents; /* # of extents freed */
|
||||
__uint16_t efd_type; /* efd log item type */
|
||||
__uint16_t efd_size; /* size of this item */
|
||||
__uint32_t efd_nextents; /* # of extents freed */
|
||||
__uint64_t efd_efi_id; /* id of corresponding efi */
|
||||
xfs_extent_t efd_extents[1]; /* array of extents freed */
|
||||
} xfs_efd_log_format_t;
|
||||
|
||||
#ifndef HAVE_FORMAT32
|
||||
typedef struct xfs_efd_log_format_32 {
|
||||
unsigned short efd_type; /* efd log item type */
|
||||
unsigned short efd_size; /* size of this item */
|
||||
uint efd_nextents; /* # of extents freed */
|
||||
__uint16_t efd_type; /* efd log item type */
|
||||
__uint16_t efd_size; /* size of this item */
|
||||
__uint32_t efd_nextents; /* # of extents freed */
|
||||
__uint64_t efd_efi_id; /* id of corresponding efi */
|
||||
xfs_extent_32_t efd_extents[1]; /* array of extents freed */
|
||||
} __attribute__((packed)) xfs_efd_log_format_32_t;
|
||||
#endif
|
||||
|
||||
typedef struct xfs_efd_log_format_64 {
|
||||
unsigned short efd_type; /* efd log item type */
|
||||
unsigned short efd_size; /* size of this item */
|
||||
uint efd_nextents; /* # of extents freed */
|
||||
__uint16_t efd_type; /* efd log item type */
|
||||
__uint16_t efd_size; /* size of this item */
|
||||
__uint32_t efd_nextents; /* # of extents freed */
|
||||
__uint64_t efd_efi_id; /* id of corresponding efi */
|
||||
xfs_extent_64_t efd_extents[1]; /* array of extents freed */
|
||||
} xfs_efd_log_format_64_t;
|
||||
|
@ -22,8 +22,6 @@
|
||||
* SGI's XFS filesystem's major stuff (constants, structures)
|
||||
*/
|
||||
|
||||
#define XFS_NAME "xfs"
|
||||
|
||||
/*
|
||||
* Direct I/O attribute record used with XFS_IOC_DIOINFO
|
||||
* d_miniosz is the min xfer size, xfer size multiple and file seek offset
|
||||
@ -426,11 +424,7 @@ typedef struct xfs_handle {
|
||||
- (char *) &(handle)) \
|
||||
+ (handle).ha_fid.xfs_fid_len)
|
||||
|
||||
#define XFS_HANDLE_CMP(h1, h2) memcmp(h1, h2, sizeof(xfs_handle_t))
|
||||
|
||||
#define FSHSIZE sizeof(fsid_t)
|
||||
|
||||
/*
|
||||
/*
|
||||
* Flags for going down operation
|
||||
*/
|
||||
#define XFS_FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */
|
||||
|
@ -458,7 +458,7 @@ nextag:
|
||||
*/
|
||||
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||
up_read(&mp->m_peraglock);
|
||||
return (xfs_buf_t *)0;
|
||||
return NULL;
|
||||
}
|
||||
agno++;
|
||||
if (agno >= agcount)
|
||||
@ -466,7 +466,7 @@ nextag:
|
||||
if (agno == pagno) {
|
||||
if (flags == 0) {
|
||||
up_read(&mp->m_peraglock);
|
||||
return (xfs_buf_t *)0;
|
||||
return NULL;
|
||||
}
|
||||
flags = 0;
|
||||
}
|
||||
@ -529,10 +529,10 @@ xfs_dialloc(
|
||||
int offset; /* index of inode in chunk */
|
||||
xfs_agino_t pagino; /* parent's a.g. relative inode # */
|
||||
xfs_agnumber_t pagno; /* parent's allocation group number */
|
||||
xfs_inobt_rec_t rec; /* inode allocation record */
|
||||
xfs_inobt_rec_incore_t rec; /* inode allocation record */
|
||||
xfs_agnumber_t tagno; /* testing allocation group number */
|
||||
xfs_btree_cur_t *tcur; /* temp cursor */
|
||||
xfs_inobt_rec_t trec; /* temp inode allocation record */
|
||||
xfs_inobt_rec_incore_t trec; /* temp inode allocation record */
|
||||
|
||||
|
||||
if (*IO_agbp == NULL) {
|
||||
@ -945,7 +945,7 @@ xfs_difree(
|
||||
int ilen; /* inodes in an inode cluster */
|
||||
xfs_mount_t *mp; /* mount structure for filesystem */
|
||||
int off; /* offset of inode in inode chunk */
|
||||
xfs_inobt_rec_t rec; /* btree record */
|
||||
xfs_inobt_rec_incore_t rec; /* btree record */
|
||||
|
||||
mp = tp->t_mountp;
|
||||
|
||||
@ -1195,6 +1195,7 @@ xfs_dilocate(
|
||||
"(0x%llx)",
|
||||
ino, XFS_AGINO_TO_INO(mp, agno, agino));
|
||||
}
|
||||
xfs_stack_trace();
|
||||
#endif /* DEBUG */
|
||||
return XFS_ERROR(EINVAL);
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ xfs_inobt_insrec(
|
||||
/*
|
||||
* Make a key out of the record data to be inserted, and save it.
|
||||
*/
|
||||
key.ir_startino = recp->ir_startino; /* INT_: direct copy */
|
||||
key.ir_startino = recp->ir_startino;
|
||||
optr = ptr = cur->bc_ptrs[level];
|
||||
/*
|
||||
* If we're off the left edge, return failure.
|
||||
@ -600,7 +600,7 @@ xfs_inobt_insrec(
|
||||
}
|
||||
#endif
|
||||
nbno = NULLAGBLOCK;
|
||||
ncur = (xfs_btree_cur_t *)0;
|
||||
ncur = NULL;
|
||||
/*
|
||||
* If the block is full, we can't insert the new entry until we
|
||||
* make the block un-full.
|
||||
@ -641,7 +641,7 @@ xfs_inobt_insrec(
|
||||
return error;
|
||||
#endif
|
||||
ptr = cur->bc_ptrs[level];
|
||||
nrec.ir_startino = nkey.ir_startino; /* INT_: direct copy */
|
||||
nrec.ir_startino = nkey.ir_startino;
|
||||
} else {
|
||||
/*
|
||||
* Otherwise the insert fails.
|
||||
@ -681,7 +681,7 @@ xfs_inobt_insrec(
|
||||
if ((error = xfs_btree_check_sptr(cur, *bnop, level)))
|
||||
return error;
|
||||
#endif
|
||||
kp[ptr - 1] = key; /* INT_: struct copy */
|
||||
kp[ptr - 1] = key;
|
||||
pp[ptr - 1] = cpu_to_be32(*bnop);
|
||||
numrecs++;
|
||||
block->bb_numrecs = cpu_to_be16(numrecs);
|
||||
@ -698,7 +698,7 @@ xfs_inobt_insrec(
|
||||
* Now stuff the new record in, bump numrecs
|
||||
* and log the new data.
|
||||
*/
|
||||
rp[ptr - 1] = *recp; /* INT_: struct copy */
|
||||
rp[ptr - 1] = *recp;
|
||||
numrecs++;
|
||||
block->bb_numrecs = cpu_to_be16(numrecs);
|
||||
xfs_inobt_log_recs(cur, bp, ptr, numrecs);
|
||||
@ -731,7 +731,7 @@ xfs_inobt_insrec(
|
||||
*/
|
||||
*bnop = nbno;
|
||||
if (nbno != NULLAGBLOCK) {
|
||||
*recp = nrec; /* INT_: struct copy */
|
||||
*recp = nrec;
|
||||
*curp = ncur;
|
||||
}
|
||||
*stat = 1;
|
||||
@ -878,7 +878,7 @@ xfs_inobt_lookup(
|
||||
*/
|
||||
bp = cur->bc_bufs[level];
|
||||
if (bp && XFS_BUF_ADDR(bp) != d)
|
||||
bp = (xfs_buf_t *)0;
|
||||
bp = NULL;
|
||||
if (!bp) {
|
||||
/*
|
||||
* Need to get a new buffer. Read it, then
|
||||
@ -950,12 +950,12 @@ xfs_inobt_lookup(
|
||||
xfs_inobt_key_t *kkp;
|
||||
|
||||
kkp = kkbase + keyno - 1;
|
||||
startino = INT_GET(kkp->ir_startino, ARCH_CONVERT);
|
||||
startino = be32_to_cpu(kkp->ir_startino);
|
||||
} else {
|
||||
xfs_inobt_rec_t *krp;
|
||||
|
||||
krp = krbase + keyno - 1;
|
||||
startino = INT_GET(krp->ir_startino, ARCH_CONVERT);
|
||||
startino = be32_to_cpu(krp->ir_startino);
|
||||
}
|
||||
/*
|
||||
* Compute difference to get next direction.
|
||||
@ -1117,7 +1117,7 @@ xfs_inobt_lshift(
|
||||
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*rpp), level)))
|
||||
return error;
|
||||
#endif
|
||||
*lpp = *rpp; /* INT_: no-change copy */
|
||||
*lpp = *rpp;
|
||||
xfs_inobt_log_ptrs(cur, lbp, nrec, nrec);
|
||||
}
|
||||
/*
|
||||
@ -1160,7 +1160,7 @@ xfs_inobt_lshift(
|
||||
} else {
|
||||
memmove(rrp, rrp + 1, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
|
||||
xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
|
||||
key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
|
||||
key.ir_startino = rrp->ir_startino;
|
||||
rkp = &key;
|
||||
}
|
||||
/*
|
||||
@ -1297,13 +1297,13 @@ xfs_inobt_newroot(
|
||||
*/
|
||||
kp = XFS_INOBT_KEY_ADDR(new, 1, cur);
|
||||
if (be16_to_cpu(left->bb_level) > 0) {
|
||||
kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); /* INT_: struct copy */
|
||||
kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); /* INT_: struct copy */
|
||||
kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur);
|
||||
kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur);
|
||||
} else {
|
||||
rp = XFS_INOBT_REC_ADDR(left, 1, cur);
|
||||
INT_COPY(kp[0].ir_startino, rp->ir_startino, ARCH_CONVERT);
|
||||
kp[0].ir_startino = rp->ir_startino;
|
||||
rp = XFS_INOBT_REC_ADDR(right, 1, cur);
|
||||
INT_COPY(kp[1].ir_startino, rp->ir_startino, ARCH_CONVERT);
|
||||
kp[1].ir_startino = rp->ir_startino;
|
||||
}
|
||||
xfs_inobt_log_keys(cur, nbp, 1, 2);
|
||||
/*
|
||||
@ -1410,8 +1410,8 @@ xfs_inobt_rshift(
|
||||
if ((error = xfs_btree_check_sptr(cur, be32_to_cpu(*lpp), level)))
|
||||
return error;
|
||||
#endif
|
||||
*rkp = *lkp; /* INT_: no change copy */
|
||||
*rpp = *lpp; /* INT_: no change copy */
|
||||
*rkp = *lkp;
|
||||
*rpp = *lpp;
|
||||
xfs_inobt_log_keys(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
|
||||
xfs_inobt_log_ptrs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
|
||||
} else {
|
||||
@ -1420,7 +1420,7 @@ xfs_inobt_rshift(
|
||||
memmove(rrp + 1, rrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
|
||||
*rrp = *lrp;
|
||||
xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs) + 1);
|
||||
key.ir_startino = rrp->ir_startino; /* INT_: direct copy */
|
||||
key.ir_startino = rrp->ir_startino;
|
||||
rkp = &key;
|
||||
}
|
||||
/*
|
||||
@ -1559,7 +1559,7 @@ xfs_inobt_split(
|
||||
rrp = XFS_INOBT_REC_ADDR(right, 1, cur);
|
||||
memcpy(rrp, lrp, be16_to_cpu(right->bb_numrecs) * sizeof(*rrp));
|
||||
xfs_inobt_log_recs(cur, rbp, 1, be16_to_cpu(right->bb_numrecs));
|
||||
keyp->ir_startino = rrp->ir_startino; /* INT_: direct copy */
|
||||
keyp->ir_startino = rrp->ir_startino;
|
||||
}
|
||||
/*
|
||||
* Find the left block number by looking in the buffer.
|
||||
@ -1813,9 +1813,9 @@ xfs_inobt_get_rec(
|
||||
* Point to the record and extract its data.
|
||||
*/
|
||||
rec = XFS_INOBT_REC_ADDR(block, ptr, cur);
|
||||
*ino = INT_GET(rec->ir_startino, ARCH_CONVERT);
|
||||
*fcnt = INT_GET(rec->ir_freecount, ARCH_CONVERT);
|
||||
*free = INT_GET(rec->ir_free, ARCH_CONVERT);
|
||||
*ino = be32_to_cpu(rec->ir_startino);
|
||||
*fcnt = be32_to_cpu(rec->ir_freecount);
|
||||
*free = be64_to_cpu(rec->ir_free);
|
||||
*stat = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -1930,10 +1930,10 @@ xfs_inobt_insert(
|
||||
|
||||
level = 0;
|
||||
nbno = NULLAGBLOCK;
|
||||
INT_SET(nrec.ir_startino, ARCH_CONVERT, cur->bc_rec.i.ir_startino);
|
||||
INT_SET(nrec.ir_freecount, ARCH_CONVERT, cur->bc_rec.i.ir_freecount);
|
||||
INT_SET(nrec.ir_free, ARCH_CONVERT, cur->bc_rec.i.ir_free);
|
||||
ncur = (xfs_btree_cur_t *)0;
|
||||
nrec.ir_startino = cpu_to_be32(cur->bc_rec.i.ir_startino);
|
||||
nrec.ir_freecount = cpu_to_be32(cur->bc_rec.i.ir_freecount);
|
||||
nrec.ir_free = cpu_to_be64(cur->bc_rec.i.ir_free);
|
||||
ncur = NULL;
|
||||
pcur = cur;
|
||||
/*
|
||||
* Loop going up the tree, starting at the leaf level.
|
||||
@ -1965,7 +1965,7 @@ xfs_inobt_insert(
|
||||
*/
|
||||
if (ncur) {
|
||||
pcur = ncur;
|
||||
ncur = (xfs_btree_cur_t *)0;
|
||||
ncur = NULL;
|
||||
}
|
||||
} while (nbno != NULLAGBLOCK);
|
||||
*stat = i;
|
||||
@ -2060,9 +2060,9 @@ xfs_inobt_update(
|
||||
/*
|
||||
* Fill in the new contents and log them.
|
||||
*/
|
||||
INT_SET(rp->ir_startino, ARCH_CONVERT, ino);
|
||||
INT_SET(rp->ir_freecount, ARCH_CONVERT, fcnt);
|
||||
INT_SET(rp->ir_free, ARCH_CONVERT, free);
|
||||
rp->ir_startino = cpu_to_be32(ino);
|
||||
rp->ir_freecount = cpu_to_be32(fcnt);
|
||||
rp->ir_free = cpu_to_be64(free);
|
||||
xfs_inobt_log_recs(cur, bp, ptr, ptr);
|
||||
/*
|
||||
* Updating first record in leaf. Pass new key value up to our parent.
|
||||
@ -2070,7 +2070,7 @@ xfs_inobt_update(
|
||||
if (ptr == 1) {
|
||||
xfs_inobt_key_t key; /* key containing [ino] */
|
||||
|
||||
INT_SET(key.ir_startino, ARCH_CONVERT, ino);
|
||||
key.ir_startino = cpu_to_be32(ino);
|
||||
if ((error = xfs_inobt_updkey(cur, &key, 1)))
|
||||
return error;
|
||||
}
|
||||
|
@ -47,19 +47,24 @@ static inline xfs_inofree_t xfs_inobt_maskn(int i, int n)
|
||||
/*
|
||||
* Data record structure
|
||||
*/
|
||||
typedef struct xfs_inobt_rec
|
||||
{
|
||||
typedef struct xfs_inobt_rec {
|
||||
__be32 ir_startino; /* starting inode number */
|
||||
__be32 ir_freecount; /* count of free inodes (set bits) */
|
||||
__be64 ir_free; /* free inode mask */
|
||||
} xfs_inobt_rec_t;
|
||||
|
||||
typedef struct xfs_inobt_rec_incore {
|
||||
xfs_agino_t ir_startino; /* starting inode number */
|
||||
__int32_t ir_freecount; /* count of free inodes (set bits) */
|
||||
xfs_inofree_t ir_free; /* free inode mask */
|
||||
} xfs_inobt_rec_t;
|
||||
} xfs_inobt_rec_incore_t;
|
||||
|
||||
|
||||
/*
|
||||
* Key structure
|
||||
*/
|
||||
typedef struct xfs_inobt_key
|
||||
{
|
||||
xfs_agino_t ir_startino; /* starting inode number */
|
||||
typedef struct xfs_inobt_key {
|
||||
__be32 ir_startino; /* starting inode number */
|
||||
} xfs_inobt_key_t;
|
||||
|
||||
/* btree pointer type */
|
||||
@ -77,7 +82,7 @@ typedef struct xfs_btree_sblock xfs_inobt_block_t;
|
||||
#define XFS_INOBT_IS_FREE(rp,i) \
|
||||
(((rp)->ir_free & XFS_INOBT_MASK(i)) != 0)
|
||||
#define XFS_INOBT_IS_FREE_DISK(rp,i) \
|
||||
((INT_GET((rp)->ir_free,ARCH_CONVERT) & XFS_INOBT_MASK(i)) != 0)
|
||||
((be64_to_cpu((rp)->ir_free) & XFS_INOBT_MASK(i)) != 0)
|
||||
#define XFS_INOBT_SET_FREE(rp,i) ((rp)->ir_free |= XFS_INOBT_MASK(i))
|
||||
#define XFS_INOBT_CLR_FREE(rp,i) ((rp)->ir_free &= ~XFS_INOBT_MASK(i))
|
||||
|
||||
|
@ -50,7 +50,7 @@ void
|
||||
xfs_ihash_init(xfs_mount_t *mp)
|
||||
{
|
||||
__uint64_t icount;
|
||||
uint i, flags = KM_SLEEP | KM_MAYFAIL;
|
||||
uint i;
|
||||
|
||||
if (!mp->m_ihsize) {
|
||||
icount = mp->m_maxicount ? mp->m_maxicount :
|
||||
@ -61,14 +61,13 @@ xfs_ihash_init(xfs_mount_t *mp)
|
||||
(64 * NBPP) / sizeof(xfs_ihash_t));
|
||||
}
|
||||
|
||||
while (!(mp->m_ihash = (xfs_ihash_t *)kmem_zalloc(mp->m_ihsize *
|
||||
sizeof(xfs_ihash_t), flags))) {
|
||||
if ((mp->m_ihsize >>= 1) <= NBPP)
|
||||
flags = KM_SLEEP;
|
||||
}
|
||||
for (i = 0; i < mp->m_ihsize; i++) {
|
||||
mp->m_ihash = kmem_zalloc_greedy(&mp->m_ihsize,
|
||||
NBPC * sizeof(xfs_ihash_t),
|
||||
mp->m_ihsize * sizeof(xfs_ihash_t),
|
||||
KM_SLEEP | KM_MAYFAIL | KM_LARGE);
|
||||
mp->m_ihsize /= sizeof(xfs_ihash_t);
|
||||
for (i = 0; i < mp->m_ihsize; i++)
|
||||
rwlock_init(&(mp->m_ihash[i].ih_lock));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -77,7 +76,7 @@ xfs_ihash_init(xfs_mount_t *mp)
|
||||
void
|
||||
xfs_ihash_free(xfs_mount_t *mp)
|
||||
{
|
||||
kmem_free(mp->m_ihash, mp->m_ihsize*sizeof(xfs_ihash_t));
|
||||
kmem_free(mp->m_ihash, mp->m_ihsize * sizeof(xfs_ihash_t));
|
||||
mp->m_ihash = NULL;
|
||||
}
|
||||
|
||||
@ -95,7 +94,7 @@ xfs_chash_init(xfs_mount_t *mp)
|
||||
mp->m_chsize = min_t(uint, mp->m_chsize, mp->m_ihsize);
|
||||
mp->m_chash = (xfs_chash_t *)kmem_zalloc(mp->m_chsize
|
||||
* sizeof(xfs_chash_t),
|
||||
KM_SLEEP);
|
||||
KM_SLEEP | KM_LARGE);
|
||||
for (i = 0; i < mp->m_chsize; i++) {
|
||||
spinlock_init(&mp->m_chash[i].ch_lock,"xfshash");
|
||||
}
|
||||
@ -244,7 +243,9 @@ again:
|
||||
|
||||
XFS_STATS_INC(xs_ig_found);
|
||||
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
ip->i_flags &= ~XFS_IRECLAIMABLE;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
version = ih->ih_version;
|
||||
read_unlock(&ih->ih_lock);
|
||||
xfs_ihash_promote(ih, ip, version);
|
||||
@ -290,15 +291,17 @@ again:
|
||||
|
||||
finish_inode:
|
||||
if (ip->i_d.di_mode == 0) {
|
||||
if (!(flags & IGET_CREATE))
|
||||
if (!(flags & XFS_IGET_CREATE))
|
||||
return ENOENT;
|
||||
xfs_iocore_inode_reinit(ip);
|
||||
}
|
||||
|
||||
|
||||
if (lock_flags != 0)
|
||||
xfs_ilock(ip, lock_flags);
|
||||
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
ip->i_flags &= ~XFS_ISTALE;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
|
||||
vn_trace_exit(vp, "xfs_iget.found",
|
||||
(inst_t *)__return_address);
|
||||
@ -320,21 +323,20 @@ finish_inode:
|
||||
* Read the disk inode attributes into a new inode structure and get
|
||||
* a new vnode for it. This should also initialize i_ino and i_mount.
|
||||
*/
|
||||
error = xfs_iread(mp, tp, ino, &ip, bno);
|
||||
if (error) {
|
||||
error = xfs_iread(mp, tp, ino, &ip, bno,
|
||||
(flags & XFS_IGET_BULKSTAT) ? XFS_IMAP_BULKSTAT : 0);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
vn_trace_exit(vp, "xfs_iget.alloc", (inst_t *)__return_address);
|
||||
|
||||
xfs_inode_lock_init(ip, vp);
|
||||
xfs_iocore_inode_init(ip);
|
||||
|
||||
if (lock_flags != 0) {
|
||||
if (lock_flags)
|
||||
xfs_ilock(ip, lock_flags);
|
||||
}
|
||||
|
||||
if ((ip->i_d.di_mode == 0) && !(flags & IGET_CREATE)) {
|
||||
|
||||
if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
|
||||
xfs_idestroy(ip);
|
||||
return ENOENT;
|
||||
}
|
||||
@ -369,7 +371,9 @@ finish_inode:
|
||||
ih->ih_next = ip;
|
||||
ip->i_udquot = ip->i_gdquot = NULL;
|
||||
ih->ih_version++;
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
ip->i_flags |= XFS_INEW;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
|
||||
write_unlock(&ih->ih_lock);
|
||||
|
||||
@ -548,7 +552,7 @@ xfs_inode_lock_init(
|
||||
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", vp->v_number);
|
||||
init_waitqueue_head(&ip->i_ipin_wait);
|
||||
atomic_set(&ip->i_pincount, 0);
|
||||
init_sema(&ip->i_flock, 1, "xfsfino", vp->v_number);
|
||||
initnsema(&ip->i_flock, 1, "xfsfino");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -854,7 +854,8 @@ xfs_iread(
|
||||
xfs_trans_t *tp,
|
||||
xfs_ino_t ino,
|
||||
xfs_inode_t **ipp,
|
||||
xfs_daddr_t bno)
|
||||
xfs_daddr_t bno,
|
||||
uint imap_flags)
|
||||
{
|
||||
xfs_buf_t *bp;
|
||||
xfs_dinode_t *dip;
|
||||
@ -866,6 +867,7 @@ xfs_iread(
|
||||
ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP);
|
||||
ip->i_ino = ino;
|
||||
ip->i_mount = mp;
|
||||
spin_lock_init(&ip->i_flags_lock);
|
||||
|
||||
/*
|
||||
* Get pointer's to the on-disk inode and the buffer containing it.
|
||||
@ -874,7 +876,7 @@ xfs_iread(
|
||||
* return NULL as well. Set i_blkno to 0 so that xfs_itobp() will
|
||||
* know that this is a new incore inode.
|
||||
*/
|
||||
error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, 0);
|
||||
error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags);
|
||||
if (error) {
|
||||
kmem_zone_free(xfs_inode_zone, ip);
|
||||
return error;
|
||||
@ -1113,7 +1115,7 @@ xfs_ialloc(
|
||||
* to prevent others from looking at until we're done.
|
||||
*/
|
||||
error = xfs_trans_iget(tp->t_mountp, tp, ino,
|
||||
IGET_CREATE, XFS_ILOCK_EXCL, &ip);
|
||||
XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip);
|
||||
if (error != 0) {
|
||||
return error;
|
||||
}
|
||||
@ -2213,7 +2215,9 @@ xfs_ifree_cluster(
|
||||
|
||||
if (ip == free_ip) {
|
||||
if (xfs_iflock_nowait(ip)) {
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
ip->i_flags |= XFS_ISTALE;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
|
||||
if (xfs_inode_clean(ip)) {
|
||||
xfs_ifunlock(ip);
|
||||
@ -2227,7 +2231,9 @@ xfs_ifree_cluster(
|
||||
|
||||
if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
|
||||
if (xfs_iflock_nowait(ip)) {
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
ip->i_flags |= XFS_ISTALE;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
|
||||
if (xfs_inode_clean(ip)) {
|
||||
xfs_ifunlock(ip);
|
||||
@ -2257,7 +2263,9 @@ xfs_ifree_cluster(
|
||||
AIL_LOCK(mp,s);
|
||||
iip->ili_flush_lsn = iip->ili_item.li_lsn;
|
||||
AIL_UNLOCK(mp, s);
|
||||
spin_lock(&iip->ili_inode->i_flags_lock);
|
||||
iip->ili_inode->i_flags |= XFS_ISTALE;
|
||||
spin_unlock(&iip->ili_inode->i_flags_lock);
|
||||
pre_flushed++;
|
||||
}
|
||||
lip = lip->li_bio_list;
|
||||
@ -2753,19 +2761,29 @@ xfs_iunpin(
|
||||
* call as the inode reclaim may be blocked waiting for
|
||||
* the inode to become unpinned.
|
||||
*/
|
||||
struct inode *inode = NULL;
|
||||
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) {
|
||||
bhv_vnode_t *vp = XFS_ITOV_NULL(ip);
|
||||
|
||||
/* make sync come back and flush this inode */
|
||||
if (vp) {
|
||||
struct inode *inode = vn_to_inode(vp);
|
||||
inode = vn_to_inode(vp);
|
||||
|
||||
if (!(inode->i_state &
|
||||
(I_NEW|I_FREEING|I_CLEAR)))
|
||||
mark_inode_dirty_sync(inode);
|
||||
(I_NEW|I_FREEING|I_CLEAR))) {
|
||||
inode = igrab(inode);
|
||||
if (inode)
|
||||
mark_inode_dirty_sync(inode);
|
||||
} else
|
||||
inode = NULL;
|
||||
}
|
||||
}
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
wake_up(&ip->i_ipin_wait);
|
||||
if (inode)
|
||||
iput(inode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,6 +267,7 @@ typedef struct xfs_inode {
|
||||
sema_t i_flock; /* inode flush lock */
|
||||
atomic_t i_pincount; /* inode pin count */
|
||||
wait_queue_head_t i_ipin_wait; /* inode pinning wait queue */
|
||||
spinlock_t i_flags_lock; /* inode i_flags lock */
|
||||
#ifdef HAVE_REFCACHE
|
||||
struct xfs_inode **i_refcache; /* ptr to entry in ref cache */
|
||||
struct xfs_inode *i_release; /* inode to unref */
|
||||
@ -388,12 +389,15 @@ typedef struct xfs_inode {
|
||||
#define XFS_INHERIT_GID(pip, vfsp) \
|
||||
(((vfsp)->vfs_flag & VFS_GRPID) || ((pip)->i_d.di_mode & S_ISGID))
|
||||
|
||||
/*
|
||||
* Flags for xfs_iget()
|
||||
*/
|
||||
#define XFS_IGET_CREATE 0x1
|
||||
#define XFS_IGET_BULKSTAT 0x2
|
||||
|
||||
/*
|
||||
* xfs_iget.c prototypes.
|
||||
*/
|
||||
|
||||
#define IGET_CREATE 1
|
||||
|
||||
void xfs_ihash_init(struct xfs_mount *);
|
||||
void xfs_ihash_free(struct xfs_mount *);
|
||||
void xfs_chash_init(struct xfs_mount *);
|
||||
@ -425,7 +429,7 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
|
||||
xfs_inode_t *, xfs_dinode_t **, struct xfs_buf **,
|
||||
xfs_daddr_t, uint);
|
||||
int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
|
||||
xfs_inode_t **, xfs_daddr_t);
|
||||
xfs_inode_t **, xfs_daddr_t, uint);
|
||||
int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int);
|
||||
int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t,
|
||||
xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t,
|
||||
|
@ -742,21 +742,6 @@ xfs_inode_item_committed(
|
||||
return (lsn);
|
||||
}
|
||||
|
||||
/*
|
||||
* The transaction with the inode locked has aborted. The inode
|
||||
* must not be dirty within the transaction (unless we're forcibly
|
||||
* shutting down). We simply unlock just as if the transaction
|
||||
* had been cancelled.
|
||||
*/
|
||||
STATIC void
|
||||
xfs_inode_item_abort(
|
||||
xfs_inode_log_item_t *iip)
|
||||
{
|
||||
xfs_inode_item_unlock(iip);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This gets called by xfs_trans_push_ail(), when IOP_TRYLOCK
|
||||
* failed to get the inode flush lock but did get the inode locked SHARED.
|
||||
@ -915,7 +900,6 @@ STATIC struct xfs_item_ops xfs_inode_item_ops = {
|
||||
.iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_inode_item_committed,
|
||||
.iop_push = (void(*)(xfs_log_item_t*))xfs_inode_item_push,
|
||||
.iop_abort = (void(*)(xfs_log_item_t*))xfs_inode_item_abort,
|
||||
.iop_pushbuf = (void(*)(xfs_log_item_t*))xfs_inode_item_pushbuf,
|
||||
.iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
|
||||
xfs_inode_item_committing
|
||||
|
@ -25,52 +25,54 @@
|
||||
* must be added on to the end.
|
||||
*/
|
||||
typedef struct xfs_inode_log_format {
|
||||
unsigned short ilf_type; /* inode log item type */
|
||||
unsigned short ilf_size; /* size of this item */
|
||||
uint ilf_fields; /* flags for fields logged */
|
||||
ushort ilf_asize; /* size of attr d/ext/root */
|
||||
ushort ilf_dsize; /* size of data/ext/root */
|
||||
xfs_ino_t ilf_ino; /* inode number */
|
||||
__uint16_t ilf_type; /* inode log item type */
|
||||
__uint16_t ilf_size; /* size of this item */
|
||||
__uint32_t ilf_fields; /* flags for fields logged */
|
||||
__uint16_t ilf_asize; /* size of attr d/ext/root */
|
||||
__uint16_t ilf_dsize; /* size of data/ext/root */
|
||||
__uint64_t ilf_ino; /* inode number */
|
||||
union {
|
||||
xfs_dev_t ilfu_rdev; /* rdev value for dev inode*/
|
||||
__uint32_t ilfu_rdev; /* rdev value for dev inode*/
|
||||
uuid_t ilfu_uuid; /* mount point value */
|
||||
} ilf_u;
|
||||
__int64_t ilf_blkno; /* blkno of inode buffer */
|
||||
int ilf_len; /* len of inode buffer */
|
||||
int ilf_boffset; /* off of inode in buffer */
|
||||
__int32_t ilf_len; /* len of inode buffer */
|
||||
__int32_t ilf_boffset; /* off of inode in buffer */
|
||||
} xfs_inode_log_format_t;
|
||||
|
||||
#ifndef HAVE_FORMAT32
|
||||
typedef struct xfs_inode_log_format_32 {
|
||||
unsigned short ilf_type; /* 16: inode log item type */
|
||||
unsigned short ilf_size; /* 16: size of this item */
|
||||
uint ilf_fields; /* 32: flags for fields logged */
|
||||
ushort ilf_asize; /* 32: size of attr d/ext/root */
|
||||
ushort ilf_dsize; /* 32: size of data/ext/root */
|
||||
xfs_ino_t ilf_ino; /* 64: inode number */
|
||||
__uint16_t ilf_type; /* inode log item type */
|
||||
__uint16_t ilf_size; /* size of this item */
|
||||
__uint32_t ilf_fields; /* flags for fields logged */
|
||||
__uint16_t ilf_asize; /* size of attr d/ext/root */
|
||||
__uint16_t ilf_dsize; /* size of data/ext/root */
|
||||
__uint64_t ilf_ino; /* inode number */
|
||||
union {
|
||||
xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
|
||||
uuid_t ilfu_uuid; /* 128: mount point value */
|
||||
__uint32_t ilfu_rdev; /* rdev value for dev inode*/
|
||||
uuid_t ilfu_uuid; /* mount point value */
|
||||
} ilf_u;
|
||||
__int64_t ilf_blkno; /* 64: blkno of inode buffer */
|
||||
int ilf_len; /* 32: len of inode buffer */
|
||||
int ilf_boffset; /* 32: off of inode in buffer */
|
||||
__int64_t ilf_blkno; /* blkno of inode buffer */
|
||||
__int32_t ilf_len; /* len of inode buffer */
|
||||
__int32_t ilf_boffset; /* off of inode in buffer */
|
||||
} __attribute__((packed)) xfs_inode_log_format_32_t;
|
||||
#endif
|
||||
|
||||
typedef struct xfs_inode_log_format_64 {
|
||||
unsigned short ilf_type; /* 16: inode log item type */
|
||||
unsigned short ilf_size; /* 16: size of this item */
|
||||
uint ilf_fields; /* 32: flags for fields logged */
|
||||
ushort ilf_asize; /* 32: size of attr d/ext/root */
|
||||
ushort ilf_dsize; /* 32: size of data/ext/root */
|
||||
__uint32_t ilf_pad; /* 32: pad for 64 bit boundary */
|
||||
xfs_ino_t ilf_ino; /* 64: inode number */
|
||||
__uint16_t ilf_type; /* inode log item type */
|
||||
__uint16_t ilf_size; /* size of this item */
|
||||
__uint32_t ilf_fields; /* flags for fields logged */
|
||||
__uint16_t ilf_asize; /* size of attr d/ext/root */
|
||||
__uint16_t ilf_dsize; /* size of data/ext/root */
|
||||
__uint32_t ilf_pad; /* pad for 64 bit boundary */
|
||||
__uint64_t ilf_ino; /* inode number */
|
||||
union {
|
||||
xfs_dev_t ilfu_rdev; /* 32: rdev value for dev inode*/
|
||||
uuid_t ilfu_uuid; /* 128: mount point value */
|
||||
__uint32_t ilfu_rdev; /* rdev value for dev inode*/
|
||||
uuid_t ilfu_uuid; /* mount point value */
|
||||
} ilf_u;
|
||||
__int64_t ilf_blkno; /* 64: blkno of inode buffer */
|
||||
int ilf_len; /* 32: len of inode buffer */
|
||||
int ilf_boffset; /* 32: off of inode in buffer */
|
||||
__int64_t ilf_blkno; /* blkno of inode buffer */
|
||||
__int32_t ilf_len; /* len of inode buffer */
|
||||
__int32_t ilf_boffset; /* off of inode in buffer */
|
||||
} xfs_inode_log_format_64_t;
|
||||
|
||||
/*
|
||||
|
@ -398,6 +398,23 @@ xfs_flush_space(
|
||||
return 1;
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_cmn_err_fsblock_zero(
|
||||
xfs_inode_t *ip,
|
||||
xfs_bmbt_irec_t *imap)
|
||||
{
|
||||
xfs_cmn_err(XFS_PTAG_FSBLOCK_ZERO, CE_ALERT, ip->i_mount,
|
||||
"Access to block zero in inode %llu "
|
||||
"start_block: %llx start_off: %llx "
|
||||
"blkcnt: %llx extent-state: %x\n",
|
||||
(unsigned long long)ip->i_ino,
|
||||
(unsigned long long)imap->br_startblock,
|
||||
(unsigned long long)imap->br_startoff,
|
||||
(unsigned long long)imap->br_blockcount,
|
||||
imap->br_state);
|
||||
return EFSCORRUPTED;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_iomap_write_direct(
|
||||
xfs_inode_t *ip,
|
||||
@ -536,23 +553,17 @@ xfs_iomap_write_direct(
|
||||
* Copy any maps to caller's array and return any error.
|
||||
*/
|
||||
if (nimaps == 0) {
|
||||
error = (ENOSPC);
|
||||
error = ENOSPC;
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if (unlikely(!imap.br_startblock && !(io->io_flags & XFS_IOCORE_RT))) {
|
||||
error = xfs_cmn_err_fsblock_zero(ip, &imap);
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
*ret_imap = imap;
|
||||
*nmaps = 1;
|
||||
if ( !(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
|
||||
cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld "
|
||||
"start_block : %llx start_off : %llx blkcnt : %llx "
|
||||
"extent-state : %x \n",
|
||||
(ip->i_mount)->m_fsname,
|
||||
(long long)ip->i_ino,
|
||||
(unsigned long long)ret_imap->br_startblock,
|
||||
(unsigned long long)ret_imap->br_startoff,
|
||||
(unsigned long long)ret_imap->br_blockcount,
|
||||
ret_imap->br_state);
|
||||
}
|
||||
return 0;
|
||||
|
||||
error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
|
||||
@ -715,17 +726,8 @@ retry:
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (!(io->io_flags & XFS_IOCORE_RT) && !ret_imap->br_startblock) {
|
||||
cmn_err(CE_PANIC,"Access to block zero: fs <%s> inode: %lld "
|
||||
"start_block : %llx start_off : %llx blkcnt : %llx "
|
||||
"extent-state : %x \n",
|
||||
(ip->i_mount)->m_fsname,
|
||||
(long long)ip->i_ino,
|
||||
(unsigned long long)ret_imap->br_startblock,
|
||||
(unsigned long long)ret_imap->br_startoff,
|
||||
(unsigned long long)ret_imap->br_blockcount,
|
||||
ret_imap->br_state);
|
||||
}
|
||||
if (unlikely(!imap[0].br_startblock && !(io->io_flags & XFS_IOCORE_RT)))
|
||||
return xfs_cmn_err_fsblock_zero(ip, &imap[0]);
|
||||
|
||||
*ret_imap = imap[0];
|
||||
*nmaps = 1;
|
||||
@ -853,24 +855,10 @@ xfs_iomap_write_allocate(
|
||||
* See if we were able to allocate an extent that
|
||||
* covers at least part of the callers request
|
||||
*/
|
||||
|
||||
for (i = 0; i < nimaps; i++) {
|
||||
if (!(io->io_flags & XFS_IOCORE_RT) &&
|
||||
!imap[i].br_startblock) {
|
||||
cmn_err(CE_PANIC,"Access to block zero: "
|
||||
"fs <%s> inode: %lld "
|
||||
"start_block : %llx start_off : %llx "
|
||||
"blkcnt : %llx extent-state : %x \n",
|
||||
(ip->i_mount)->m_fsname,
|
||||
(long long)ip->i_ino,
|
||||
(unsigned long long)
|
||||
imap[i].br_startblock,
|
||||
(unsigned long long)
|
||||
imap[i].br_startoff,
|
||||
(unsigned long long)
|
||||
imap[i].br_blockcount,
|
||||
imap[i].br_state);
|
||||
}
|
||||
if (unlikely(!imap[i].br_startblock &&
|
||||
!(io->io_flags & XFS_IOCORE_RT)))
|
||||
return xfs_cmn_err_fsblock_zero(ip, &imap[i]);
|
||||
if ((offset_fsb >= imap[i].br_startoff) &&
|
||||
(offset_fsb < (imap[i].br_startoff +
|
||||
imap[i].br_blockcount))) {
|
||||
@ -941,7 +929,7 @@ xfs_iomap_write_unwritten(
|
||||
XFS_WRITE_LOG_COUNT);
|
||||
if (error) {
|
||||
xfs_trans_cancel(tp, 0);
|
||||
goto error0;
|
||||
return XFS_ERROR(error);
|
||||
}
|
||||
|
||||
xfs_ilock(ip, XFS_ILOCK_EXCL);
|
||||
@ -967,19 +955,11 @@ xfs_iomap_write_unwritten(
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
if (error)
|
||||
goto error0;
|
||||
return XFS_ERROR(error);
|
||||
|
||||
if ( !(io->io_flags & XFS_IOCORE_RT) && !imap.br_startblock) {
|
||||
cmn_err(CE_PANIC,"Access to block zero: fs <%s> "
|
||||
"inode: %lld start_block : %llx start_off : "
|
||||
"%llx blkcnt : %llx extent-state : %x \n",
|
||||
(ip->i_mount)->m_fsname,
|
||||
(long long)ip->i_ino,
|
||||
(unsigned long long)imap.br_startblock,
|
||||
(unsigned long long)imap.br_startoff,
|
||||
(unsigned long long)imap.br_blockcount,
|
||||
imap.br_state);
|
||||
}
|
||||
if (unlikely(!imap.br_startblock &&
|
||||
!(io->io_flags & XFS_IOCORE_RT)))
|
||||
return xfs_cmn_err_fsblock_zero(ip, &imap);
|
||||
|
||||
if ((numblks_fsb = imap.br_blockcount) == 0) {
|
||||
/*
|
||||
@ -999,6 +979,5 @@ error_on_bmapi_transaction:
|
||||
xfs_bmap_cancel(&free_list);
|
||||
xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT));
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
error0:
|
||||
return XFS_ERROR(error);
|
||||
}
|
||||
|
@ -39,6 +39,16 @@
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_btree.h"
|
||||
|
||||
int
|
||||
xfs_internal_inum(
|
||||
xfs_mount_t *mp,
|
||||
xfs_ino_t ino)
|
||||
{
|
||||
return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
|
||||
(XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
|
||||
(ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)));
|
||||
}
|
||||
|
||||
STATIC int
|
||||
xfs_bulkstat_one_iget(
|
||||
xfs_mount_t *mp, /* mount point for filesystem */
|
||||
@ -52,7 +62,8 @@ xfs_bulkstat_one_iget(
|
||||
bhv_vnode_t *vp;
|
||||
int error;
|
||||
|
||||
error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
|
||||
error = xfs_iget(mp, NULL, ino,
|
||||
XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno);
|
||||
if (error) {
|
||||
*stat = BULKSTAT_RV_NOTHING;
|
||||
return error;
|
||||
@ -212,17 +223,12 @@ xfs_bulkstat_one(
|
||||
xfs_dinode_t *dip; /* dinode inode pointer */
|
||||
|
||||
dip = (xfs_dinode_t *)dibuff;
|
||||
*stat = BULKSTAT_RV_NOTHING;
|
||||
|
||||
if (!buffer || ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
|
||||
(XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
|
||||
(ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))) {
|
||||
*stat = BULKSTAT_RV_NOTHING;
|
||||
if (!buffer || xfs_internal_inum(mp, ino))
|
||||
return XFS_ERROR(EINVAL);
|
||||
}
|
||||
if (ubsize < sizeof(*buf)) {
|
||||
*stat = BULKSTAT_RV_NOTHING;
|
||||
if (ubsize < sizeof(*buf))
|
||||
return XFS_ERROR(ENOMEM);
|
||||
}
|
||||
|
||||
buf = kmem_alloc(sizeof(*buf), KM_SLEEP);
|
||||
|
||||
@ -238,8 +244,7 @@ xfs_bulkstat_one(
|
||||
}
|
||||
|
||||
if (copy_to_user(buffer, buf, sizeof(*buf))) {
|
||||
*stat = BULKSTAT_RV_NOTHING;
|
||||
error = EFAULT;
|
||||
error = EFAULT;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
@ -252,6 +257,46 @@ xfs_bulkstat_one(
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test to see whether we can use the ondisk inode directly, based
|
||||
* on the given bulkstat flags, filling in dipp accordingly.
|
||||
* Returns zero if the inode is dodgey.
|
||||
*/
|
||||
STATIC int
|
||||
xfs_bulkstat_use_dinode(
|
||||
xfs_mount_t *mp,
|
||||
int flags,
|
||||
xfs_buf_t *bp,
|
||||
int clustidx,
|
||||
xfs_dinode_t **dipp)
|
||||
{
|
||||
xfs_dinode_t *dip;
|
||||
unsigned int aformat;
|
||||
|
||||
*dipp = NULL;
|
||||
if (!bp || (flags & BULKSTAT_FG_IGET))
|
||||
return 1;
|
||||
dip = (xfs_dinode_t *)
|
||||
xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog);
|
||||
if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC ||
|
||||
!XFS_DINODE_GOOD_VERSION(
|
||||
INT_GET(dip->di_core.di_version, ARCH_CONVERT)))
|
||||
return 0;
|
||||
if (flags & BULKSTAT_FG_QUICK) {
|
||||
*dipp = dip;
|
||||
return 1;
|
||||
}
|
||||
/* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */
|
||||
aformat = INT_GET(dip->di_core.di_aformat, ARCH_CONVERT);
|
||||
if ((XFS_CFORK_Q(&dip->di_core) == 0) ||
|
||||
(aformat == XFS_DINODE_FMT_LOCAL) ||
|
||||
(aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) {
|
||||
*dipp = dip;
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return stat information in bulk (by-inode) for the filesystem.
|
||||
*/
|
||||
@ -284,10 +329,11 @@ xfs_bulkstat(
|
||||
xfs_agino_t gino; /* current btree rec's start inode */
|
||||
int i; /* loop index */
|
||||
int icount; /* count of inodes good in irbuf */
|
||||
size_t irbsize; /* size of irec buffer in bytes */
|
||||
xfs_ino_t ino; /* inode number (filesystem) */
|
||||
xfs_inobt_rec_t *irbp; /* current irec buffer pointer */
|
||||
xfs_inobt_rec_t *irbuf; /* start of irec buffer */
|
||||
xfs_inobt_rec_t *irbufend; /* end of good irec buffer entries */
|
||||
xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */
|
||||
xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */
|
||||
xfs_inobt_rec_incore_t *irbufend; /* end of good irec buffer entries */
|
||||
xfs_ino_t lastino=0; /* last inode number returned */
|
||||
int nbcluster; /* # of blocks in a cluster */
|
||||
int nicluster; /* # of inodes in a cluster */
|
||||
@ -328,13 +374,10 @@ xfs_bulkstat(
|
||||
(XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog);
|
||||
nimask = ~(nicluster - 1);
|
||||
nbcluster = nicluster >> mp->m_sb.sb_inopblog;
|
||||
/*
|
||||
* Allocate a page-sized buffer for inode btree records.
|
||||
* We could try allocating something smaller, but for normal
|
||||
* calls we'll always (potentially) need the whole page.
|
||||
*/
|
||||
irbuf = kmem_alloc(NBPC, KM_SLEEP);
|
||||
nirbuf = NBPC / sizeof(*irbuf);
|
||||
irbuf = kmem_zalloc_greedy(&irbsize, NBPC, NBPC * 4,
|
||||
KM_SLEEP | KM_MAYFAIL | KM_LARGE);
|
||||
nirbuf = irbsize / sizeof(*irbuf);
|
||||
|
||||
/*
|
||||
* Loop over the allocation groups, starting from the last
|
||||
* inode returned; 0 means start of the allocation group.
|
||||
@ -358,7 +401,7 @@ xfs_bulkstat(
|
||||
* Allocate and initialize a btree cursor for ialloc btree.
|
||||
*/
|
||||
cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO,
|
||||
(xfs_inode_t *)0, 0);
|
||||
(xfs_inode_t *)0, 0);
|
||||
irbp = irbuf;
|
||||
irbufend = irbuf + nirbuf;
|
||||
end_of_ag = 0;
|
||||
@ -395,9 +438,9 @@ xfs_bulkstat(
|
||||
gcnt++;
|
||||
}
|
||||
gfree |= XFS_INOBT_MASKN(0, chunkidx);
|
||||
INT_SET(irbp->ir_startino, ARCH_CONVERT, gino);
|
||||
INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt);
|
||||
INT_SET(irbp->ir_free, ARCH_CONVERT, gfree);
|
||||
irbp->ir_startino = gino;
|
||||
irbp->ir_freecount = gcnt;
|
||||
irbp->ir_free = gfree;
|
||||
irbp++;
|
||||
agino = gino + XFS_INODES_PER_CHUNK;
|
||||
icount = XFS_INODES_PER_CHUNK - gcnt;
|
||||
@ -451,11 +494,27 @@ xfs_bulkstat(
|
||||
}
|
||||
/*
|
||||
* If this chunk has any allocated inodes, save it.
|
||||
* Also start read-ahead now for this chunk.
|
||||
*/
|
||||
if (gcnt < XFS_INODES_PER_CHUNK) {
|
||||
INT_SET(irbp->ir_startino, ARCH_CONVERT, gino);
|
||||
INT_SET(irbp->ir_freecount, ARCH_CONVERT, gcnt);
|
||||
INT_SET(irbp->ir_free, ARCH_CONVERT, gfree);
|
||||
/*
|
||||
* Loop over all clusters in the next chunk.
|
||||
* Do a readahead if there are any allocated
|
||||
* inodes in that cluster.
|
||||
*/
|
||||
for (agbno = XFS_AGINO_TO_AGBNO(mp, gino),
|
||||
chunkidx = 0;
|
||||
chunkidx < XFS_INODES_PER_CHUNK;
|
||||
chunkidx += nicluster,
|
||||
agbno += nbcluster) {
|
||||
if (XFS_INOBT_MASKN(chunkidx,
|
||||
nicluster) & ~gfree)
|
||||
xfs_btree_reada_bufs(mp, agno,
|
||||
agbno, nbcluster);
|
||||
}
|
||||
irbp->ir_startino = gino;
|
||||
irbp->ir_freecount = gcnt;
|
||||
irbp->ir_free = gfree;
|
||||
irbp++;
|
||||
icount += XFS_INODES_PER_CHUNK - gcnt;
|
||||
}
|
||||
@ -478,34 +537,12 @@ xfs_bulkstat(
|
||||
irbufend = irbp;
|
||||
for (irbp = irbuf;
|
||||
irbp < irbufend && ubleft >= statstruct_size; irbp++) {
|
||||
/*
|
||||
* Read-ahead the next chunk's worth of inodes.
|
||||
*/
|
||||
if (&irbp[1] < irbufend) {
|
||||
/*
|
||||
* Loop over all clusters in the next chunk.
|
||||
* Do a readahead if there are any allocated
|
||||
* inodes in that cluster.
|
||||
*/
|
||||
for (agbno = XFS_AGINO_TO_AGBNO(mp,
|
||||
INT_GET(irbp[1].ir_startino, ARCH_CONVERT)),
|
||||
chunkidx = 0;
|
||||
chunkidx < XFS_INODES_PER_CHUNK;
|
||||
chunkidx += nicluster,
|
||||
agbno += nbcluster) {
|
||||
if (XFS_INOBT_MASKN(chunkidx,
|
||||
nicluster) &
|
||||
~(INT_GET(irbp[1].ir_free, ARCH_CONVERT)))
|
||||
xfs_btree_reada_bufs(mp, agno,
|
||||
agbno, nbcluster);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now process this chunk of inodes.
|
||||
*/
|
||||
for (agino = INT_GET(irbp->ir_startino, ARCH_CONVERT), chunkidx = 0, clustidx = 0;
|
||||
for (agino = irbp->ir_startino, chunkidx = clustidx = 0;
|
||||
ubleft > 0 &&
|
||||
INT_GET(irbp->ir_freecount, ARCH_CONVERT) < XFS_INODES_PER_CHUNK;
|
||||
irbp->ir_freecount < XFS_INODES_PER_CHUNK;
|
||||
chunkidx++, clustidx++, agino++) {
|
||||
ASSERT(chunkidx < XFS_INODES_PER_CHUNK);
|
||||
/*
|
||||
@ -525,11 +562,12 @@ xfs_bulkstat(
|
||||
*/
|
||||
if ((chunkidx & (nicluster - 1)) == 0) {
|
||||
agbno = XFS_AGINO_TO_AGBNO(mp,
|
||||
INT_GET(irbp->ir_startino, ARCH_CONVERT)) +
|
||||
irbp->ir_startino) +
|
||||
((chunkidx & nimask) >>
|
||||
mp->m_sb.sb_inopblog);
|
||||
|
||||
if (flags & BULKSTAT_FG_QUICK) {
|
||||
if (flags & (BULKSTAT_FG_QUICK |
|
||||
BULKSTAT_FG_INLINE)) {
|
||||
ino = XFS_AGINO_TO_INO(mp, agno,
|
||||
agino);
|
||||
bno = XFS_AGB_TO_DADDR(mp, agno,
|
||||
@ -543,6 +581,7 @@ xfs_bulkstat(
|
||||
KM_SLEEP);
|
||||
ip->i_ino = ino;
|
||||
ip->i_mount = mp;
|
||||
spin_lock_init(&ip->i_flags_lock);
|
||||
if (bp)
|
||||
xfs_buf_relse(bp);
|
||||
error = xfs_itobp(mp, NULL, ip,
|
||||
@ -564,30 +603,34 @@ xfs_bulkstat(
|
||||
/*
|
||||
* Skip if this inode is free.
|
||||
*/
|
||||
if (XFS_INOBT_MASK(chunkidx) & INT_GET(irbp->ir_free, ARCH_CONVERT))
|
||||
if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free)
|
||||
continue;
|
||||
/*
|
||||
* Count used inodes as free so we can tell
|
||||
* when the chunk is used up.
|
||||
*/
|
||||
INT_MOD(irbp->ir_freecount, ARCH_CONVERT, +1);
|
||||
irbp->ir_freecount++;
|
||||
ino = XFS_AGINO_TO_INO(mp, agno, agino);
|
||||
bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
|
||||
if (flags & BULKSTAT_FG_QUICK) {
|
||||
dip = (xfs_dinode_t *)xfs_buf_offset(bp,
|
||||
(clustidx << mp->m_sb.sb_inodelog));
|
||||
|
||||
if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT)
|
||||
!= XFS_DINODE_MAGIC
|
||||
|| !XFS_DINODE_GOOD_VERSION(
|
||||
INT_GET(dip->di_core.di_version, ARCH_CONVERT)))
|
||||
continue;
|
||||
if (!xfs_bulkstat_use_dinode(mp, flags, bp,
|
||||
clustidx, &dip))
|
||||
continue;
|
||||
/*
|
||||
* If we need to do an iget, cannot hold bp.
|
||||
* Drop it, until starting the next cluster.
|
||||
*/
|
||||
if ((flags & BULKSTAT_FG_INLINE) && !dip) {
|
||||
if (bp)
|
||||
xfs_buf_relse(bp);
|
||||
bp = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the inode and fill in a single buffer.
|
||||
* BULKSTAT_FG_QUICK uses dip to fill it in.
|
||||
* BULKSTAT_FG_IGET uses igets.
|
||||
* BULKSTAT_FG_INLINE uses dip if we have an
|
||||
* inline attr fork, else igets.
|
||||
* See: xfs_bulkstat_one & xfs_dm_bulkstat_one.
|
||||
* This is also used to count inodes/blks, etc
|
||||
* in xfs_qm_quotacheck.
|
||||
@ -597,8 +640,15 @@ xfs_bulkstat(
|
||||
ubleft, private_data,
|
||||
bno, &ubused, dip, &fmterror);
|
||||
if (fmterror == BULKSTAT_RV_NOTHING) {
|
||||
if (error == ENOMEM)
|
||||
if (error == EFAULT) {
|
||||
ubleft = 0;
|
||||
rval = error;
|
||||
break;
|
||||
}
|
||||
else if (error == ENOMEM)
|
||||
ubleft = 0;
|
||||
else
|
||||
lastino = ino;
|
||||
continue;
|
||||
}
|
||||
if (fmterror == BULKSTAT_RV_GIVEUP) {
|
||||
@ -633,7 +683,7 @@ xfs_bulkstat(
|
||||
/*
|
||||
* Done, we're either out of filesystem or space to put the data.
|
||||
*/
|
||||
kmem_free(irbuf, NBPC);
|
||||
kmem_free(irbuf, irbsize);
|
||||
*ubcountp = ubelem;
|
||||
if (agno >= mp->m_sb.sb_agcount) {
|
||||
/*
|
||||
|
@ -36,15 +36,16 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
|
||||
/*
|
||||
* Values for stat return value.
|
||||
*/
|
||||
#define BULKSTAT_RV_NOTHING 0
|
||||
#define BULKSTAT_RV_DIDONE 1
|
||||
#define BULKSTAT_RV_GIVEUP 2
|
||||
#define BULKSTAT_RV_NOTHING 0
|
||||
#define BULKSTAT_RV_DIDONE 1
|
||||
#define BULKSTAT_RV_GIVEUP 2
|
||||
|
||||
/*
|
||||
* Values for bulkstat flag argument.
|
||||
*/
|
||||
#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
|
||||
#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
|
||||
#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
|
||||
#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
|
||||
#define BULKSTAT_FG_INLINE 0x4 /* No iget if inline attrs */
|
||||
|
||||
/*
|
||||
* Return stat information in bulk (by-inode) for the filesystem.
|
||||
@ -80,6 +81,11 @@ xfs_bulkstat_one(
|
||||
void *dibuff,
|
||||
int *stat);
|
||||
|
||||
int
|
||||
xfs_internal_inum(
|
||||
xfs_mount_t *mp,
|
||||
xfs_ino_t ino);
|
||||
|
||||
int /* error status */
|
||||
xfs_inumbers(
|
||||
xfs_mount_t *mp, /* mount point for filesystem */
|
||||
|
@ -617,7 +617,8 @@ xfs_log_unmount_write(xfs_mount_t *mp)
|
||||
reg[0].i_len = sizeof(magic);
|
||||
XLOG_VEC_SET_TYPE(®[0], XLOG_REG_TYPE_UNMOUNT);
|
||||
|
||||
error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0, 0);
|
||||
error = xfs_log_reserve(mp, 600, 1, &tic,
|
||||
XFS_LOG, 0, XLOG_UNMOUNT_REC_TYPE);
|
||||
if (!error) {
|
||||
/* remove inited flag */
|
||||
((xlog_ticket_t *)tic)->t_flags = 0;
|
||||
@ -655,8 +656,11 @@ xfs_log_unmount_write(xfs_mount_t *mp)
|
||||
} else {
|
||||
LOG_UNLOCK(log, s);
|
||||
}
|
||||
if (tic)
|
||||
if (tic) {
|
||||
xlog_trace_loggrant(log, tic, "unmount rec");
|
||||
xlog_ungrant_log_space(log, tic);
|
||||
xlog_state_put_ticket(log, tic);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We're already in forced_shutdown mode, couldn't
|
||||
@ -1196,7 +1200,7 @@ xlog_alloc_log(xfs_mount_t *mp,
|
||||
kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP);
|
||||
iclog = *iclogp;
|
||||
iclog->hic_data = (xlog_in_core_2_t *)
|
||||
kmem_zalloc(iclogsize, KM_SLEEP);
|
||||
kmem_zalloc(iclogsize, KM_SLEEP | KM_LARGE);
|
||||
|
||||
iclog->ic_prev = prev_iclog;
|
||||
prev_iclog = iclog;
|
||||
@ -2212,9 +2216,13 @@ xlog_state_do_callback(
|
||||
|
||||
iclog = iclog->ic_next;
|
||||
} while (first_iclog != iclog);
|
||||
if (repeats && (repeats % 10) == 0) {
|
||||
|
||||
if (repeats > 5000) {
|
||||
flushcnt += repeats;
|
||||
repeats = 0;
|
||||
xfs_fs_cmn_err(CE_WARN, log->l_mp,
|
||||
"xlog_state_do_callback: looping %d", repeats);
|
||||
"%s: possible infinite loop (%d iterations)",
|
||||
__FUNCTION__, flushcnt);
|
||||
}
|
||||
} while (!ioerrors && loopdidcallbacks);
|
||||
|
||||
@ -2246,6 +2254,7 @@ xlog_state_do_callback(
|
||||
}
|
||||
#endif
|
||||
|
||||
flushcnt = 0;
|
||||
if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR)) {
|
||||
flushcnt = log->l_flushcnt;
|
||||
log->l_flushcnt = 0;
|
||||
|
@ -47,17 +47,11 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
|
||||
* Macros, structures, prototypes for interface to the log manager.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Flags to xfs_log_mount
|
||||
*/
|
||||
#define XFS_LOG_RECOVER 0x1
|
||||
|
||||
/*
|
||||
* Flags to xfs_log_done()
|
||||
*/
|
||||
#define XFS_LOG_REL_PERM_RESERV 0x1
|
||||
|
||||
|
||||
/*
|
||||
* Flags to xfs_log_reserve()
|
||||
*
|
||||
@ -70,8 +64,6 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
|
||||
#define XFS_LOG_SLEEP 0x0
|
||||
#define XFS_LOG_NOSLEEP 0x1
|
||||
#define XFS_LOG_PERM_RESERV 0x2
|
||||
#define XFS_LOG_RESV_ALL (XFS_LOG_NOSLEEP|XFS_LOG_PERM_RESERV)
|
||||
|
||||
|
||||
/*
|
||||
* Flags to xfs_log_force()
|
||||
|
@ -32,7 +32,6 @@ struct xfs_mount;
|
||||
#define XLOG_MIN_ICLOGS 2
|
||||
#define XLOG_MED_ICLOGS 4
|
||||
#define XLOG_MAX_ICLOGS 8
|
||||
#define XLOG_CALLBACK_SIZE 10
|
||||
#define XLOG_HEADER_MAGIC_NUM 0xFEEDbabe /* Invalid cycle number */
|
||||
#define XLOG_VERSION_1 1
|
||||
#define XLOG_VERSION_2 2 /* Large IClogs, Log sunit */
|
||||
@ -149,9 +148,6 @@ struct xfs_mount;
|
||||
#define XLOG_WAS_CONT_TRANS 0x08 /* Cont this trans into new region */
|
||||
#define XLOG_END_TRANS 0x10 /* End a continued transaction */
|
||||
#define XLOG_UNMOUNT_TRANS 0x20 /* Unmount a filesystem transaction */
|
||||
#define XLOG_SKIP_TRANS (XLOG_COMMIT_TRANS | XLOG_CONTINUE_TRANS | \
|
||||
XLOG_WAS_CONT_TRANS | XLOG_END_TRANS | \
|
||||
XLOG_UNMOUNT_TRANS)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/*
|
||||
@ -506,6 +502,12 @@ extern int xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
|
||||
#define XLOG_TRACE_SLEEP_FLUSH 3
|
||||
#define XLOG_TRACE_WAKE_FLUSH 4
|
||||
|
||||
/*
|
||||
* Unmount record type is used as a pseudo transaction type for the ticket.
|
||||
* It's value must be outside the range of XFS_TRANS_* values.
|
||||
*/
|
||||
#define XLOG_UNMOUNT_REC_TYPE (-1U)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __XFS_LOG_PRIV_H__ */
|
||||
|
@ -331,7 +331,7 @@ typedef struct xfs_mount {
|
||||
xfs_agnumber_t m_agirotor; /* last ag dir inode alloced */
|
||||
lock_t m_agirotor_lock;/* .. and lock protecting it */
|
||||
xfs_agnumber_t m_maxagi; /* highest inode alloc group */
|
||||
uint m_ihsize; /* size of next field */
|
||||
size_t m_ihsize; /* size of next field */
|
||||
struct xfs_ihash *m_ihash; /* fs private inode hash table*/
|
||||
struct xfs_inode *m_inodes; /* active inode list */
|
||||
struct list_head m_del_inodes; /* inodes to reclaim */
|
||||
@ -541,7 +541,8 @@ static inline xfs_mount_t *xfs_bhvtom(bhv_desc_t *bdp)
|
||||
#define XFS_VFSTOM(vfs) xfs_vfstom(vfs)
|
||||
static inline xfs_mount_t *xfs_vfstom(bhv_vfs_t *vfs)
|
||||
{
|
||||
return XFS_BHVTOM(bhv_lookup(VFS_BHVHEAD(vfs), &xfs_vfsops));
|
||||
return XFS_BHVTOM(bhv_lookup_range(VFS_BHVHEAD(vfs),
|
||||
VFS_POSITION_XFS, VFS_POSITION_XFS));
|
||||
}
|
||||
|
||||
#define XFS_DADDR_TO_AGNO(mp,d) xfs_daddr_to_agno(mp,d)
|
||||
|
@ -281,8 +281,6 @@ typedef struct xfs_qoff_logformat {
|
||||
XFS_UQUOTA_CHKD|XFS_PQUOTA_ACCT|\
|
||||
XFS_OQUOTA_ENFD|XFS_OQUOTA_CHKD|\
|
||||
XFS_GQUOTA_ACCT)
|
||||
#define XFS_MOUNT_QUOTA_MASK (XFS_MOUNT_QUOTA_ALL | XFS_UQUOTA_ACTIVE | \
|
||||
XFS_GQUOTA_ACTIVE | XFS_PQUOTA_ACTIVE)
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1948,7 +1948,7 @@ xfs_growfs_rt(
|
||||
*/
|
||||
nrextents = nrblocks;
|
||||
do_div(nrextents, in->extsize);
|
||||
nrbmblocks = roundup_64(nrextents, NBBY * sbp->sb_blocksize);
|
||||
nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize);
|
||||
nrextslog = xfs_highbit32(nrextents);
|
||||
nrsumlevels = nrextslog + 1;
|
||||
nrsumsize = (uint)sizeof(xfs_suminfo_t) * nrsumlevels * nrbmblocks;
|
||||
@ -1976,7 +1976,10 @@ xfs_growfs_rt(
|
||||
if ((error = xfs_growfs_rt_alloc(mp, rsumblocks, nrsumblocks,
|
||||
mp->m_sb.sb_rsumino)))
|
||||
return error;
|
||||
nmp = NULL;
|
||||
/*
|
||||
* Allocate a new (fake) mount/sb.
|
||||
*/
|
||||
nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP);
|
||||
/*
|
||||
* Loop over the bitmap blocks.
|
||||
* We will do everything one bitmap block at a time.
|
||||
@ -1987,10 +1990,6 @@ xfs_growfs_rt(
|
||||
((sbp->sb_rextents & ((1 << mp->m_blkbit_log) - 1)) != 0);
|
||||
bmbno < nrbmblocks;
|
||||
bmbno++) {
|
||||
/*
|
||||
* Allocate a new (fake) mount/sb.
|
||||
*/
|
||||
nmp = kmem_alloc(sizeof(*nmp), KM_SLEEP);
|
||||
*nmp = *mp;
|
||||
nsbp = &nmp->m_sb;
|
||||
/*
|
||||
@ -2018,13 +2017,13 @@ xfs_growfs_rt(
|
||||
cancelflags = 0;
|
||||
if ((error = xfs_trans_reserve(tp, 0,
|
||||
XFS_GROWRTFREE_LOG_RES(nmp), 0, 0, 0)))
|
||||
goto error_exit;
|
||||
break;
|
||||
/*
|
||||
* Lock out other callers by grabbing the bitmap inode lock.
|
||||
*/
|
||||
if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0,
|
||||
XFS_ILOCK_EXCL, &ip)))
|
||||
goto error_exit;
|
||||
break;
|
||||
ASSERT(ip == mp->m_rbmip);
|
||||
/*
|
||||
* Update the bitmap inode's size.
|
||||
@ -2038,7 +2037,7 @@ xfs_growfs_rt(
|
||||
*/
|
||||
if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino, 0,
|
||||
XFS_ILOCK_EXCL, &ip)))
|
||||
goto error_exit;
|
||||
break;
|
||||
ASSERT(ip == mp->m_rsumip);
|
||||
/*
|
||||
* Update the summary inode's size.
|
||||
@ -2053,7 +2052,7 @@ xfs_growfs_rt(
|
||||
mp->m_rsumlevels != nmp->m_rsumlevels) {
|
||||
error = xfs_rtcopy_summary(mp, nmp, tp);
|
||||
if (error)
|
||||
goto error_exit;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Update superblock fields.
|
||||
@ -2080,17 +2079,12 @@ xfs_growfs_rt(
|
||||
error = xfs_rtfree_range(nmp, tp, sbp->sb_rextents,
|
||||
nsbp->sb_rextents - sbp->sb_rextents, &bp, &sumbno);
|
||||
if (error)
|
||||
goto error_exit;
|
||||
break;
|
||||
/*
|
||||
* Mark more blocks free in the superblock.
|
||||
*/
|
||||
xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS,
|
||||
nsbp->sb_rextents - sbp->sb_rextents);
|
||||
/*
|
||||
* Free the fake mp structure.
|
||||
*/
|
||||
kmem_free(nmp, sizeof(*nmp));
|
||||
nmp = NULL;
|
||||
/*
|
||||
* Update mp values into the real mp structure.
|
||||
*/
|
||||
@ -2101,15 +2095,15 @@ xfs_growfs_rt(
|
||||
*/
|
||||
xfs_trans_commit(tp, 0, NULL);
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (error)
|
||||
xfs_trans_cancel(tp, cancelflags);
|
||||
|
||||
/*
|
||||
* Error paths come here.
|
||||
* Free the fake mp structure.
|
||||
*/
|
||||
error_exit:
|
||||
if (nmp)
|
||||
kmem_free(nmp, sizeof(*nmp));
|
||||
xfs_trans_cancel(tp, cancelflags);
|
||||
kmem_free(nmp, sizeof(*nmp));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -60,10 +60,6 @@ struct xfs_mount;
|
||||
XFS_SB_VERSION_LOGV2BIT | \
|
||||
XFS_SB_VERSION_SECTORBIT | \
|
||||
XFS_SB_VERSION_MOREBITSBIT)
|
||||
#define XFS_SB_VERSION_OKSASHBITS \
|
||||
(XFS_SB_VERSION_NUMBITS | \
|
||||
XFS_SB_VERSION_REALFBITS | \
|
||||
XFS_SB_VERSION_OKSASHFBITS)
|
||||
#define XFS_SB_VERSION_OKREALBITS \
|
||||
(XFS_SB_VERSION_NUMBITS | \
|
||||
XFS_SB_VERSION_OKREALFBITS | \
|
||||
@ -81,9 +77,6 @@ struct xfs_mount;
|
||||
#define XFS_SB_VERSION2_RESERVED2BIT 0x00000002
|
||||
#define XFS_SB_VERSION2_RESERVED4BIT 0x00000004
|
||||
#define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */
|
||||
#define XFS_SB_VERSION2_SASHFBITS 0xff000000 /* Mask: features that
|
||||
require changing
|
||||
PROM and SASH */
|
||||
|
||||
#define XFS_SB_VERSION2_OKREALFBITS \
|
||||
(XFS_SB_VERSION2_ATTR2BIT)
|
||||
@ -238,12 +231,6 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp)
|
||||
}
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#define XFS_SB_GOOD_SASH_VERSION(sbp) \
|
||||
((((sbp)->sb_versionnum >= XFS_SB_VERSION_1) && \
|
||||
((sbp)->sb_versionnum <= XFS_SB_VERSION_3)) || \
|
||||
((XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
|
||||
!((sbp)->sb_versionnum & ~XFS_SB_VERSION_OKSASHBITS)))
|
||||
|
||||
#define XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v)
|
||||
static inline unsigned xfs_sb_version_tonew(unsigned v)
|
||||
{
|
||||
@ -461,15 +448,6 @@ static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp)
|
||||
* File system sector to basic block conversions.
|
||||
*/
|
||||
#define XFS_FSS_TO_BB(mp,sec) ((sec) << (mp)->m_sectbb_log)
|
||||
#define XFS_BB_TO_FSS(mp,bb) \
|
||||
(((bb) + (XFS_FSS_TO_BB(mp,1) - 1)) >> (mp)->m_sectbb_log)
|
||||
#define XFS_BB_TO_FSST(mp,bb) ((bb) >> (mp)->m_sectbb_log)
|
||||
|
||||
/*
|
||||
* File system sector to byte conversions.
|
||||
*/
|
||||
#define XFS_FSS_TO_B(mp,sectno) ((xfs_fsize_t)(sectno) << (mp)->m_sb.sb_sectlog)
|
||||
#define XFS_B_TO_FSST(mp,b) (((__uint64_t)(b)) >> (mp)->m_sb.sb_sectlog)
|
||||
|
||||
/*
|
||||
* File system block to basic block conversions.
|
||||
|
@ -149,7 +149,6 @@ typedef struct xfs_item_ops {
|
||||
void (*iop_unlock)(xfs_log_item_t *);
|
||||
xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
|
||||
void (*iop_push)(xfs_log_item_t *);
|
||||
void (*iop_abort)(xfs_log_item_t *);
|
||||
void (*iop_pushbuf)(xfs_log_item_t *);
|
||||
void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
|
||||
} xfs_item_ops_t;
|
||||
@ -163,7 +162,6 @@ typedef struct xfs_item_ops {
|
||||
#define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip)
|
||||
#define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn)
|
||||
#define IOP_PUSH(ip) (*(ip)->li_ops->iop_push)(ip)
|
||||
#define IOP_ABORT(ip) (*(ip)->li_ops->iop_abort)(ip)
|
||||
#define IOP_PUSHBUF(ip) (*(ip)->li_ops->iop_pushbuf)(ip)
|
||||
#define IOP_COMMITTING(ip, lsn) (*(ip)->li_ops->iop_committing)(ip, lsn)
|
||||
|
||||
|
@ -276,7 +276,7 @@ xfs_trans_update_ail(
|
||||
xfs_mount_t *mp,
|
||||
xfs_log_item_t *lip,
|
||||
xfs_lsn_t lsn,
|
||||
unsigned long s)
|
||||
unsigned long s) __releases(mp->m_ail_lock)
|
||||
{
|
||||
xfs_ail_entry_t *ailp;
|
||||
xfs_log_item_t *dlip=NULL;
|
||||
@ -328,7 +328,7 @@ void
|
||||
xfs_trans_delete_ail(
|
||||
xfs_mount_t *mp,
|
||||
xfs_log_item_t *lip,
|
||||
unsigned long s)
|
||||
unsigned long s) __releases(mp->m_ail_lock)
|
||||
{
|
||||
xfs_ail_entry_t *ailp;
|
||||
xfs_log_item_t *dlip;
|
||||
|
@ -46,11 +46,13 @@ xfs_log_busy_slot_t *xfs_trans_add_busy(xfs_trans_t *tp,
|
||||
/*
|
||||
* From xfs_trans_ail.c
|
||||
*/
|
||||
void xfs_trans_update_ail(struct xfs_mount *,
|
||||
struct xfs_log_item *, xfs_lsn_t,
|
||||
unsigned long);
|
||||
void xfs_trans_delete_ail(struct xfs_mount *,
|
||||
struct xfs_log_item *, unsigned long);
|
||||
void xfs_trans_update_ail(struct xfs_mount *mp,
|
||||
struct xfs_log_item *lip, xfs_lsn_t lsn,
|
||||
unsigned long s)
|
||||
__releases(mp->m_ail_lock);
|
||||
void xfs_trans_delete_ail(struct xfs_mount *mp,
|
||||
struct xfs_log_item *lip, unsigned long s)
|
||||
__releases(mp->m_ail_lock);
|
||||
struct xfs_log_item *xfs_trans_first_ail(struct xfs_mount *, int *);
|
||||
struct xfs_log_item *xfs_trans_next_ail(struct xfs_mount *,
|
||||
struct xfs_log_item *, int *, int *);
|
||||
|
@ -1922,7 +1922,7 @@ xfs_showargs(
|
||||
}
|
||||
|
||||
if (mp->m_flags & XFS_MOUNT_IHASHSIZE)
|
||||
seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize);
|
||||
seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", (int)mp->m_ihsize);
|
||||
|
||||
if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
|
||||
seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
|
||||
|
@ -2366,10 +2366,15 @@ xfs_remove(
|
||||
|
||||
namelen = VNAMELEN(dentry);
|
||||
|
||||
if (!xfs_get_dir_entry(dentry, &ip)) {
|
||||
dm_di_mode = ip->i_d.di_mode;
|
||||
IRELE(ip);
|
||||
}
|
||||
|
||||
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
|
||||
error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dir_vp,
|
||||
DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
|
||||
name, NULL, 0, 0, 0);
|
||||
name, NULL, dm_di_mode, 0, 0);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
@ -2995,7 +3000,7 @@ xfs_rmdir(
|
||||
int cancel_flags;
|
||||
int committed;
|
||||
bhv_vnode_t *dir_vp;
|
||||
int dm_di_mode = 0;
|
||||
int dm_di_mode = S_IFDIR;
|
||||
int last_cdp_link;
|
||||
int namelen;
|
||||
uint resblks;
|
||||
@ -3010,11 +3015,16 @@ xfs_rmdir(
|
||||
return XFS_ERROR(EIO);
|
||||
namelen = VNAMELEN(dentry);
|
||||
|
||||
if (!xfs_get_dir_entry(dentry, &cdp)) {
|
||||
dm_di_mode = cdp->i_d.di_mode;
|
||||
IRELE(cdp);
|
||||
}
|
||||
|
||||
if (DM_EVENT_ENABLED(dir_vp->v_vfsp, dp, DM_EVENT_REMOVE)) {
|
||||
error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE,
|
||||
dir_vp, DM_RIGHT_NULL,
|
||||
NULL, DM_RIGHT_NULL,
|
||||
name, NULL, 0, 0, 0);
|
||||
name, NULL, dm_di_mode, 0, 0);
|
||||
if (error)
|
||||
return XFS_ERROR(error);
|
||||
}
|
||||
@ -3834,7 +3844,9 @@ xfs_reclaim(
|
||||
XFS_MOUNT_ILOCK(mp);
|
||||
vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip));
|
||||
list_add_tail(&ip->i_reclaim, &mp->m_del_inodes);
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
ip->i_flags |= XFS_IRECLAIMABLE;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
XFS_MOUNT_IUNLOCK(mp);
|
||||
}
|
||||
return 0;
|
||||
@ -3859,8 +3871,10 @@ xfs_finish_reclaim(
|
||||
* us.
|
||||
*/
|
||||
write_lock(&ih->ih_lock);
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
if ((ip->i_flags & XFS_IRECLAIM) ||
|
||||
(!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) {
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
write_unlock(&ih->ih_lock);
|
||||
if (locked) {
|
||||
xfs_ifunlock(ip);
|
||||
@ -3869,6 +3883,7 @@ xfs_finish_reclaim(
|
||||
return 1;
|
||||
}
|
||||
ip->i_flags |= XFS_IRECLAIM;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
write_unlock(&ih->ih_lock);
|
||||
|
||||
/*
|
||||
@ -4272,7 +4287,7 @@ xfs_free_file_space(
|
||||
xfs_mount_t *mp;
|
||||
int nimap;
|
||||
uint resblks;
|
||||
int rounding;
|
||||
uint rounding;
|
||||
int rt;
|
||||
xfs_fileoff_t startoffset_fsb;
|
||||
xfs_trans_t *tp;
|
||||
@ -4313,8 +4328,7 @@ xfs_free_file_space(
|
||||
vn_iowait(vp); /* wait for the completion of any pending DIOs */
|
||||
}
|
||||
|
||||
rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog),
|
||||
(__uint8_t)NBPP);
|
||||
rounding = max_t(uint, 1 << mp->m_sb.sb_blocklog, NBPP);
|
||||
ilen = len + (offset & (rounding - 1));
|
||||
ioffset = offset & ~(rounding - 1);
|
||||
if (ilen & (rounding - 1))
|
||||
|
Loading…
Reference in New Issue
Block a user