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:
Linus Torvalds 2006-09-29 09:36:55 -07:00
commit c0341b0f47
64 changed files with 1058 additions and 1035 deletions

View file

@ -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

View file

@ -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)
{

View file

@ -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);
/*

View file

@ -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)

View file

@ -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) \

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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 },

View file

@ -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;

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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);

View file

@ -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);

View file

@ -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 */

View file

@ -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.

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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__ */

View file

@ -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) {

View file

@ -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;
/*

View file

@ -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,

View file

@ -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;

View file

@ -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];

View file

@ -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__ */

View file

@ -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

View file

@ -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;
/*

View file

@ -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.

View file

@ -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__ */

View file

@ -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);

View file

@ -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;

View file

@ -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))

View file

@ -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:

View file

@ -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.
*/

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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 */

View file

@ -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

View file

@ -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;

View file

@ -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 */

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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))

View file

@ -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");
}
/*

View file

@ -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);
}
}

View file

@ -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,

View file

@ -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

View file

@ -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;
/*

View file

@ -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);
}

View file

@ -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) {
/*

View file

@ -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 */

View file

@ -617,7 +617,8 @@ xfs_log_unmount_write(xfs_mount_t *mp)
reg[0].i_len = sizeof(magic);
XLOG_VEC_SET_TYPE(&reg[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;

View file

@ -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()

View file

@ -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__ */

View file

@ -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)

View file

@ -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)
/*

View file

@ -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;
}

View file

@ -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.

View file

@ -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)

View file

@ -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;

View file

@ -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 *);

View file

@ -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",

View file

@ -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))