Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6

* 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6: (37 commits)
  [XFS] Fix lockdep annotations for xfs_lock_inodes
  [LIB]: export radix_tree_preload()
  [XFS] Fix XFS_IOC_FSBULKSTAT{,_SINGLE} & XFS_IOC_FSINUMBERS in compat mode
  [XFS] Compat ioctl handler for handle operations
  [XFS] Compat ioctl handler for XFS_IOC_FSGEOMETRY_V1.
  [XFS] Clean up function name handling in tracing code
  [XFS] Quota inode has no parent.
  [XFS] Concurrent Multi-File Data Streams
  [XFS] Use uninitialized_var macro to stop warning about rtx
  [XFS] XFS should not be looking at filp reference counts
  [XFS] Use is_power_of_2 instead of open coding checks
  [XFS] Reduce shouting by removing unnecessary macros from dir2 code.
  [XFS] Simplify XFS min/max macros.
  [XFS] Kill off xfs_count_bits
  [XFS] Cancel transactions on xfs_itruncate_start error.
  [XFS] Use do_div() on 64 bit types.
  [XFS] Fix remount,readonly path to flush everything correctly.
  [XFS] Cleanup inode extent size hint extraction
  [XFS] Prevent ENOSPC from aborting transactions that need to succeed
  [XFS] Prevent deadlock when flushing inodes on unmount
  ...
This commit is contained in:
Linus Torvalds
2007-07-15 16:43:43 -07:00
66 changed files with 3263 additions and 1140 deletions

View File

@@ -64,6 +64,7 @@ xfs-y += xfs_alloc.o \
xfs_dir2_sf.o \
xfs_error.o \
xfs_extfree_item.o \
xfs_filestream.o \
xfs_fsops.o \
xfs_ialloc.o \
xfs_ialloc_btree.o \
@@ -77,6 +78,7 @@ xfs-y += xfs_alloc.o \
xfs_log.o \
xfs_log_recover.o \
xfs_mount.o \
xfs_mru_cache.o \
xfs_rename.o \
xfs_trans.o \
xfs_trans_ail.o \

View File

@@ -100,25 +100,6 @@ kmem_zone_destroy(kmem_zone_t *zone)
extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);
/*
* Low memory cache shrinkers
*/
typedef struct shrinker *kmem_shaker_t;
typedef int (*kmem_shake_func_t)(int, gfp_t);
static inline kmem_shaker_t
kmem_shake_register(kmem_shake_func_t sfunc)
{
return set_shrinker(DEFAULT_SEEKS, sfunc);
}
static inline void
kmem_shake_deregister(kmem_shaker_t shrinker)
{
remove_shrinker(shrinker);
}
static inline int
kmem_shake_allow(gfp_t gfp_mask)
{

View File

@@ -108,14 +108,19 @@ xfs_page_trace(
/*
* Schedule IO completion handling on a xfsdatad if this was
* the final hold on this ioend.
* the final hold on this ioend. If we are asked to wait,
* flush the workqueue.
*/
STATIC void
xfs_finish_ioend(
xfs_ioend_t *ioend)
xfs_ioend_t *ioend,
int wait)
{
if (atomic_dec_and_test(&ioend->io_remaining))
if (atomic_dec_and_test(&ioend->io_remaining)) {
queue_work(xfsdatad_workqueue, &ioend->io_work);
if (wait)
flush_workqueue(xfsdatad_workqueue);
}
}
/*
@@ -156,6 +161,8 @@ xfs_setfilesize(
xfs_fsize_t bsize;
ip = xfs_vtoi(ioend->io_vnode);
if (!ip)
return;
ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
ASSERT(ioend->io_type != IOMAP_READ);
@@ -334,7 +341,7 @@ xfs_end_bio(
bio->bi_end_io = NULL;
bio_put(bio);
xfs_finish_ioend(ioend);
xfs_finish_ioend(ioend, 0);
return 0;
}
@@ -470,7 +477,7 @@ xfs_submit_ioend(
}
if (bio)
xfs_submit_ioend_bio(ioend, bio);
xfs_finish_ioend(ioend);
xfs_finish_ioend(ioend, 0);
} while ((ioend = next) != NULL);
}
@@ -1003,6 +1010,8 @@ xfs_page_state_convert(
if (buffer_unwritten(bh) || buffer_delay(bh) ||
((buffer_uptodate(bh) || PageUptodate(page)) &&
!buffer_mapped(bh) && (unmapped || startio))) {
int new_ioend = 0;
/*
* Make sure we don't use a read-only iomap
*/
@@ -1021,6 +1030,15 @@ xfs_page_state_convert(
}
if (!iomap_valid) {
/*
* if we didn't have a valid mapping then we
* need to ensure that we put the new mapping
* in a new ioend structure. This needs to be
* done to ensure that the ioends correctly
* reflect the block mappings at io completion
* for unwritten extent conversion.
*/
new_ioend = 1;
if (type == IOMAP_NEW) {
size = xfs_probe_cluster(inode,
page, bh, head, 0);
@@ -1040,7 +1058,7 @@ xfs_page_state_convert(
if (startio) {
xfs_add_to_ioend(inode, bh, offset,
type, &ioend,
!iomap_valid);
new_ioend);
} else {
set_buffer_dirty(bh);
unlock_buffer(bh);
@@ -1416,6 +1434,13 @@ xfs_end_io_direct(
* This is not necessary for synchronous direct I/O, but we do
* it anyway to keep the code uniform and simpler.
*
* Well, if only it were that simple. Because synchronous direct I/O
* requires extent conversion to occur *before* we return to userspace,
* we have to wait for extent conversion to complete. Look at the
* iocb that has been passed to us to determine if this is AIO or
* not. If it is synchronous, tell xfs_finish_ioend() to kick the
* workqueue and wait for it to complete.
*
* The core direct I/O code might be changed to always call the
* completion handler in the future, in which case all this can
* go away.
@@ -1423,9 +1448,9 @@ xfs_end_io_direct(
ioend->io_offset = offset;
ioend->io_size = size;
if (ioend->io_type == IOMAP_READ) {
xfs_finish_ioend(ioend);
xfs_finish_ioend(ioend, 0);
} else if (private && size > 0) {
xfs_finish_ioend(ioend);
xfs_finish_ioend(ioend, is_sync_kiocb(iocb));
} else {
/*
* A direct I/O write ioend starts it's life in unwritten
@@ -1434,7 +1459,7 @@ xfs_end_io_direct(
* handler.
*/
INIT_WORK(&ioend->io_work, xfs_end_bio_written);
xfs_finish_ioend(ioend);
xfs_finish_ioend(ioend, 0);
}
/*

View File

@@ -35,7 +35,7 @@
#include <linux/freezer.h>
static kmem_zone_t *xfs_buf_zone;
static kmem_shaker_t xfs_buf_shake;
static struct shrinker *xfs_buf_shake;
STATIC int xfsbufd(void *);
STATIC int xfsbufd_wakeup(int, gfp_t);
STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int);
@@ -314,7 +314,7 @@ xfs_buf_free(
ASSERT(list_empty(&bp->b_hash_list));
if (bp->b_flags & _XBF_PAGE_CACHE) {
if (bp->b_flags & (_XBF_PAGE_CACHE|_XBF_PAGES)) {
uint i;
if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1))
@@ -323,18 +323,11 @@ xfs_buf_free(
for (i = 0; i < bp->b_page_count; i++) {
struct page *page = bp->b_pages[i];
ASSERT(!PagePrivate(page));
if (bp->b_flags & _XBF_PAGE_CACHE)
ASSERT(!PagePrivate(page));
page_cache_release(page);
}
_xfs_buf_free_pages(bp);
} else if (bp->b_flags & _XBF_KMEM_ALLOC) {
/*
* XXX(hch): bp->b_count_desired might be incorrect (see
* xfs_buf_associate_memory for details), but fortunately
* the Linux version of kmem_free ignores the len argument..
*/
kmem_free(bp->b_addr, bp->b_count_desired);
_xfs_buf_free_pages(bp);
}
xfs_buf_deallocate(bp);
@@ -764,43 +757,44 @@ xfs_buf_get_noaddr(
size_t len,
xfs_buftarg_t *target)
{
size_t malloc_len = len;
unsigned long page_count = PAGE_ALIGN(len) >> PAGE_SHIFT;
int error, i;
xfs_buf_t *bp;
void *data;
int error;
bp = xfs_buf_allocate(0);
if (unlikely(bp == NULL))
goto fail;
_xfs_buf_initialize(bp, target, 0, len, 0);
try_again:
data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE);
if (unlikely(data == NULL))
error = _xfs_buf_get_pages(bp, page_count, 0);
if (error)
goto fail_free_buf;
/* check whether alignment matches.. */
if ((__psunsigned_t)data !=
((__psunsigned_t)data & ~target->bt_smask)) {
/* .. else double the size and try again */
kmem_free(data, malloc_len);
malloc_len <<= 1;
goto try_again;
for (i = 0; i < page_count; i++) {
bp->b_pages[i] = alloc_page(GFP_KERNEL);
if (!bp->b_pages[i])
goto fail_free_mem;
}
bp->b_flags |= _XBF_PAGES;
error = xfs_buf_associate_memory(bp, data, len);
if (error)
error = _xfs_buf_map_pages(bp, XBF_MAPPED);
if (unlikely(error)) {
printk(KERN_WARNING "%s: failed to map pages\n",
__FUNCTION__);
goto fail_free_mem;
bp->b_flags |= _XBF_KMEM_ALLOC;
}
xfs_buf_unlock(bp);
XB_TRACE(bp, "no_daddr", data);
XB_TRACE(bp, "no_daddr", len);
return bp;
fail_free_mem:
kmem_free(data, malloc_len);
while (--i >= 0)
__free_page(bp->b_pages[i]);
_xfs_buf_free_pages(bp);
fail_free_buf:
xfs_buf_free(bp);
xfs_buf_deallocate(bp);
fail:
return NULL;
}
@@ -1453,6 +1447,7 @@ xfs_free_buftarg(
int external)
{
xfs_flush_buftarg(btp, 1);
xfs_blkdev_issue_flush(btp);
if (external)
xfs_blkdev_put(btp->bt_bdev);
xfs_free_bufhash(btp);
@@ -1837,7 +1832,7 @@ xfs_buf_init(void)
if (!xfsdatad_workqueue)
goto out_destroy_xfslogd_workqueue;
xfs_buf_shake = kmem_shake_register(xfsbufd_wakeup);
xfs_buf_shake = set_shrinker(DEFAULT_SEEKS, xfsbufd_wakeup);
if (!xfs_buf_shake)
goto out_destroy_xfsdatad_workqueue;
@@ -1859,7 +1854,7 @@ xfs_buf_init(void)
void
xfs_buf_terminate(void)
{
kmem_shake_deregister(xfs_buf_shake);
remove_shrinker(xfs_buf_shake);
destroy_workqueue(xfsdatad_workqueue);
destroy_workqueue(xfslogd_workqueue);
kmem_zone_destroy(xfs_buf_zone);

View File

@@ -63,7 +63,7 @@ typedef enum {
/* flags used only internally */
_XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */
_XBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc() */
_XBF_PAGES = (1 << 18), /* backed by refcounted pages */
_XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */
_XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */
} xfs_buf_flags_t;

View File

@@ -183,15 +183,6 @@ xfs_file_open(
return -bhv_vop_open(vn_from_inode(inode), NULL);
}
STATIC int
xfs_file_close(
struct file *filp,
fl_owner_t id)
{
return -bhv_vop_close(vn_from_inode(filp->f_path.dentry->d_inode), 0,
file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL);
}
STATIC int
xfs_file_release(
struct inode *inode,
@@ -436,7 +427,6 @@ const struct file_operations xfs_file_operations = {
#endif
.mmap = xfs_file_mmap,
.open = xfs_file_open,
.flush = xfs_file_close,
.release = xfs_file_release,
.fsync = xfs_file_fsync,
#ifdef HAVE_FOP_OPEN_EXEC
@@ -458,7 +448,6 @@ const struct file_operations xfs_invis_file_operations = {
#endif
.mmap = xfs_file_mmap,
.open = xfs_file_open,
.flush = xfs_file_close,
.release = xfs_file_release,
.fsync = xfs_file_fsync,
};

View File

@@ -46,6 +46,7 @@ xfs_param_t xfs_params = {
.inherit_nosym = { 0, 0, 1 },
.rotorstep = { 1, 1, 255 },
.inherit_nodfrg = { 0, 1, 1 },
.fstrm_timer = { 1, 50, 3600*100},
};
/*

View File

@@ -1019,7 +1019,7 @@ xfs_ioc_bulkstat(
if (cmd == XFS_IOC_FSINUMBERS)
error = xfs_inumbers(mp, &inlast, &count,
bulkreq.ubuffer);
bulkreq.ubuffer, xfs_inumbers_fmt);
else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE)
error = xfs_bulkstat_single(mp, &inlast,
bulkreq.ubuffer, &done);

View File

@@ -23,10 +23,25 @@
#include <linux/fs.h>
#include <asm/uaccess.h>
#include "xfs.h"
#include "xfs_types.h"
#include "xfs_fs.h"
#include "xfs_bit.h"
#include "xfs_log.h"
#include "xfs_inum.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_attr_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_vfs.h"
#include "xfs_vnode.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_itable.h"
#include "xfs_error.h"
#include "xfs_dfrag.h"
#define _NATIVE_IOC(cmd, type) \
@@ -34,6 +49,7 @@
#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
#define BROKEN_X86_ALIGNMENT
#define _PACKED __attribute__((packed))
/* on ia32 l_start is on a 32-bit boundary */
typedef struct xfs_flock64_32 {
__s16 l_type;
@@ -75,35 +91,276 @@ xfs_ioctl32_flock(
return (unsigned long)p;
}
typedef struct compat_xfs_fsop_geom_v1 {
__u32 blocksize; /* filesystem (data) block size */
__u32 rtextsize; /* realtime extent size */
__u32 agblocks; /* fsblocks in an AG */
__u32 agcount; /* number of allocation groups */
__u32 logblocks; /* fsblocks in the log */
__u32 sectsize; /* (data) sector size, bytes */
__u32 inodesize; /* inode size in bytes */
__u32 imaxpct; /* max allowed inode space(%) */
__u64 datablocks; /* fsblocks in data subvolume */
__u64 rtblocks; /* fsblocks in realtime subvol */
__u64 rtextents; /* rt extents in realtime subvol*/
__u64 logstart; /* starting fsblock of the log */
unsigned char uuid[16]; /* unique id of the filesystem */
__u32 sunit; /* stripe unit, fsblocks */
__u32 swidth; /* stripe width, fsblocks */
__s32 version; /* structure version */
__u32 flags; /* superblock version flags */
__u32 logsectsize; /* log sector size, bytes */
__u32 rtsectsize; /* realtime sector size, bytes */
__u32 dirblocksize; /* directory block size, bytes */
} __attribute__((packed)) compat_xfs_fsop_geom_v1_t;
#define XFS_IOC_FSGEOMETRY_V1_32 \
_IOR ('X', 100, struct compat_xfs_fsop_geom_v1)
STATIC unsigned long xfs_ioctl32_geom_v1(unsigned long arg)
{
compat_xfs_fsop_geom_v1_t __user *p32 = (void __user *)arg;
xfs_fsop_geom_v1_t __user *p = compat_alloc_user_space(sizeof(*p));
if (copy_in_user(p, p32, sizeof(*p32)))
return -EFAULT;
return (unsigned long)p;
}
typedef struct compat_xfs_inogrp {
__u64 xi_startino; /* starting inode number */
__s32 xi_alloccount; /* # bits set in allocmask */
__u64 xi_allocmask; /* mask of allocated inodes */
} __attribute__((packed)) compat_xfs_inogrp_t;
STATIC int xfs_inumbers_fmt_compat(
void __user *ubuffer,
const xfs_inogrp_t *buffer,
long count,
long *written)
{
compat_xfs_inogrp_t *p32 = ubuffer;
long i;
for (i = 0; i < count; i++) {
if (put_user(buffer[i].xi_startino, &p32[i].xi_startino) ||
put_user(buffer[i].xi_alloccount, &p32[i].xi_alloccount) ||
put_user(buffer[i].xi_allocmask, &p32[i].xi_allocmask))
return -EFAULT;
}
*written = count * sizeof(*p32);
return 0;
}
#else
typedef struct xfs_fsop_bulkreq32 {
#define xfs_inumbers_fmt_compat xfs_inumbers_fmt
#define _PACKED
#endif
/* XFS_IOC_FSBULKSTAT and friends */
typedef struct compat_xfs_bstime {
__s32 tv_sec; /* seconds */
__s32 tv_nsec; /* and nanoseconds */
} compat_xfs_bstime_t;
STATIC int xfs_bstime_store_compat(
compat_xfs_bstime_t __user *p32,
const xfs_bstime_t *p)
{
__s32 sec32;
sec32 = p->tv_sec;
if (put_user(sec32, &p32->tv_sec) ||
put_user(p->tv_nsec, &p32->tv_nsec))
return -EFAULT;
return 0;
}
typedef struct compat_xfs_bstat {
__u64 bs_ino; /* inode number */
__u16 bs_mode; /* type and mode */
__u16 bs_nlink; /* number of links */
__u32 bs_uid; /* user id */
__u32 bs_gid; /* group id */
__u32 bs_rdev; /* device value */
__s32 bs_blksize; /* block size */
__s64 bs_size; /* file size */
compat_xfs_bstime_t bs_atime; /* access time */
compat_xfs_bstime_t bs_mtime; /* modify time */
compat_xfs_bstime_t bs_ctime; /* inode change time */
int64_t bs_blocks; /* number of blocks */
__u32 bs_xflags; /* extended flags */
__s32 bs_extsize; /* extent size */
__s32 bs_extents; /* number of extents */
__u32 bs_gen; /* generation count */
__u16 bs_projid; /* project id */
unsigned char bs_pad[14]; /* pad space, unused */
__u32 bs_dmevmask; /* DMIG event mask */
__u16 bs_dmstate; /* DMIG state info */
__u16 bs_aextents; /* attribute number of extents */
} _PACKED compat_xfs_bstat_t;
STATIC int xfs_bulkstat_one_fmt_compat(
void __user *ubuffer,
const xfs_bstat_t *buffer)
{
compat_xfs_bstat_t __user *p32 = ubuffer;
if (put_user(buffer->bs_ino, &p32->bs_ino) ||
put_user(buffer->bs_mode, &p32->bs_mode) ||
put_user(buffer->bs_nlink, &p32->bs_nlink) ||
put_user(buffer->bs_uid, &p32->bs_uid) ||
put_user(buffer->bs_gid, &p32->bs_gid) ||
put_user(buffer->bs_rdev, &p32->bs_rdev) ||
put_user(buffer->bs_blksize, &p32->bs_blksize) ||
put_user(buffer->bs_size, &p32->bs_size) ||
xfs_bstime_store_compat(&p32->bs_atime, &buffer->bs_atime) ||
xfs_bstime_store_compat(&p32->bs_mtime, &buffer->bs_mtime) ||
xfs_bstime_store_compat(&p32->bs_ctime, &buffer->bs_ctime) ||
put_user(buffer->bs_blocks, &p32->bs_blocks) ||
put_user(buffer->bs_xflags, &p32->bs_xflags) ||
put_user(buffer->bs_extsize, &p32->bs_extsize) ||
put_user(buffer->bs_extents, &p32->bs_extents) ||
put_user(buffer->bs_gen, &p32->bs_gen) ||
put_user(buffer->bs_projid, &p32->bs_projid) ||
put_user(buffer->bs_dmevmask, &p32->bs_dmevmask) ||
put_user(buffer->bs_dmstate, &p32->bs_dmstate) ||
put_user(buffer->bs_aextents, &p32->bs_aextents))
return -EFAULT;
return sizeof(*p32);
}
typedef struct compat_xfs_fsop_bulkreq {
compat_uptr_t lastip; /* last inode # pointer */
__s32 icount; /* count of entries in buffer */
compat_uptr_t ubuffer; /* user buffer for inode desc. */
__s32 ocount; /* output count pointer */
} xfs_fsop_bulkreq32_t;
compat_uptr_t ocount; /* output count pointer */
} compat_xfs_fsop_bulkreq_t;
STATIC unsigned long
xfs_ioctl32_bulkstat(
unsigned long arg)
#define XFS_IOC_FSBULKSTAT_32 \
_IOWR('X', 101, struct compat_xfs_fsop_bulkreq)
#define XFS_IOC_FSBULKSTAT_SINGLE_32 \
_IOWR('X', 102, struct compat_xfs_fsop_bulkreq)
#define XFS_IOC_FSINUMBERS_32 \
_IOWR('X', 103, struct compat_xfs_fsop_bulkreq)
/* copied from xfs_ioctl.c */
STATIC int
xfs_ioc_bulkstat_compat(
xfs_mount_t *mp,
unsigned int cmd,
void __user *arg)
{
xfs_fsop_bulkreq32_t __user *p32 = (void __user *)arg;
xfs_fsop_bulkreq_t __user *p = compat_alloc_user_space(sizeof(*p));
compat_xfs_fsop_bulkreq_t __user *p32 = (void __user *)arg;
u32 addr;
xfs_fsop_bulkreq_t bulkreq;
int count; /* # of records returned */
xfs_ino_t inlast; /* last inode number */
int done;
int error;
if (get_user(addr, &p32->lastip) ||
put_user(compat_ptr(addr), &p->lastip) ||
copy_in_user(&p->icount, &p32->icount, sizeof(s32)) ||
get_user(addr, &p32->ubuffer) ||
put_user(compat_ptr(addr), &p->ubuffer) ||
get_user(addr, &p32->ocount) ||
put_user(compat_ptr(addr), &p->ocount))
/* done = 1 if there are more stats to get and if bulkstat */
/* should be called again (unused here, but used in dmapi) */
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (XFS_FORCED_SHUTDOWN(mp))
return -XFS_ERROR(EIO);
if (get_user(addr, &p32->lastip))
return -EFAULT;
bulkreq.lastip = compat_ptr(addr);
if (get_user(bulkreq.icount, &p32->icount) ||
get_user(addr, &p32->ubuffer))
return -EFAULT;
bulkreq.ubuffer = compat_ptr(addr);
if (get_user(addr, &p32->ocount))
return -EFAULT;
bulkreq.ocount = compat_ptr(addr);
if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64)))
return -XFS_ERROR(EFAULT);
if ((count = bulkreq.icount) <= 0)
return -XFS_ERROR(EINVAL);
if (cmd == XFS_IOC_FSINUMBERS)
error = xfs_inumbers(mp, &inlast, &count,
bulkreq.ubuffer, xfs_inumbers_fmt_compat);
else {
/* declare a var to get a warning in case the type changes */
bulkstat_one_fmt_pf formatter = xfs_bulkstat_one_fmt_compat;
error = xfs_bulkstat(mp, &inlast, &count,
xfs_bulkstat_one, formatter,
sizeof(compat_xfs_bstat_t), bulkreq.ubuffer,
BULKSTAT_FG_QUICK, &done);
}
if (error)
return -error;
if (bulkreq.ocount != NULL) {
if (copy_to_user(bulkreq.lastip, &inlast,
sizeof(xfs_ino_t)))
return -XFS_ERROR(EFAULT);
if (copy_to_user(bulkreq.ocount, &count, sizeof(count)))
return -XFS_ERROR(EFAULT);
}
return 0;
}
typedef struct compat_xfs_fsop_handlereq {
__u32 fd; /* fd for FD_TO_HANDLE */
compat_uptr_t path; /* user pathname */
__u32 oflags; /* open flags */
compat_uptr_t ihandle; /* user supplied handle */
__u32 ihandlen; /* user supplied length */
compat_uptr_t ohandle; /* user buffer for handle */
compat_uptr_t ohandlen; /* user buffer length */
} compat_xfs_fsop_handlereq_t;
#define XFS_IOC_PATH_TO_FSHANDLE_32 \
_IOWR('X', 104, struct compat_xfs_fsop_handlereq)
#define XFS_IOC_PATH_TO_HANDLE_32 \
_IOWR('X', 105, struct compat_xfs_fsop_handlereq)
#define XFS_IOC_FD_TO_HANDLE_32 \
_IOWR('X', 106, struct compat_xfs_fsop_handlereq)
#define XFS_IOC_OPEN_BY_HANDLE_32 \
_IOWR('X', 107, struct compat_xfs_fsop_handlereq)
#define XFS_IOC_READLINK_BY_HANDLE_32 \
_IOWR('X', 108, struct compat_xfs_fsop_handlereq)
STATIC unsigned long xfs_ioctl32_fshandle(unsigned long arg)
{
compat_xfs_fsop_handlereq_t __user *p32 = (void __user *)arg;
xfs_fsop_handlereq_t __user *p = compat_alloc_user_space(sizeof(*p));
u32 addr;
if (copy_in_user(&p->fd, &p32->fd, sizeof(__u32)) ||
get_user(addr, &p32->path) ||
put_user(compat_ptr(addr), &p->path) ||
copy_in_user(&p->oflags, &p32->oflags, sizeof(__u32)) ||
get_user(addr, &p32->ihandle) ||
put_user(compat_ptr(addr), &p->ihandle) ||
copy_in_user(&p->ihandlen, &p32->ihandlen, sizeof(__u32)) ||
get_user(addr, &p32->ohandle) ||
put_user(compat_ptr(addr), &p->ohandle) ||
get_user(addr, &p32->ohandlen) ||
put_user(compat_ptr(addr), &p->ohandlen))
return -EFAULT;
return (unsigned long)p;
}
#endif
STATIC long
xfs_compat_ioctl(
@@ -118,7 +375,6 @@ xfs_compat_ioctl(
switch (cmd) {
case XFS_IOC_DIOINFO:
case XFS_IOC_FSGEOMETRY_V1:
case XFS_IOC_FSGEOMETRY:
case XFS_IOC_GETVERSION:
case XFS_IOC_GETXFLAGS:
@@ -131,12 +387,7 @@ xfs_compat_ioctl(
case XFS_IOC_GETBMAPA:
case XFS_IOC_GETBMAPX:
/* not handled
case XFS_IOC_FD_TO_HANDLE:
case XFS_IOC_PATH_TO_HANDLE:
case XFS_IOC_PATH_TO_FSHANDLE:
case XFS_IOC_OPEN_BY_HANDLE:
case XFS_IOC_FSSETDM_BY_HANDLE:
case XFS_IOC_READLINK_BY_HANDLE:
case XFS_IOC_ATTRLIST_BY_HANDLE:
case XFS_IOC_ATTRMULTI_BY_HANDLE:
*/
@@ -166,6 +417,10 @@ xfs_compat_ioctl(
arg = xfs_ioctl32_flock(arg);
cmd = _NATIVE_IOC(cmd, struct xfs_flock64);
break;
case XFS_IOC_FSGEOMETRY_V1_32:
arg = xfs_ioctl32_geom_v1(arg);
cmd = _NATIVE_IOC(cmd, struct xfs_fsop_geom_v1);
break;
#else /* These are handled fine if no alignment issues */
case XFS_IOC_ALLOCSP:
@@ -176,18 +431,28 @@ xfs_compat_ioctl(
case XFS_IOC_FREESP64:
case XFS_IOC_RESVSP64:
case XFS_IOC_UNRESVSP64:
case XFS_IOC_FSGEOMETRY_V1:
break;
/* xfs_bstat_t still has wrong u32 vs u64 alignment */
case XFS_IOC_SWAPEXT:
break;
case XFS_IOC_FSBULKSTAT_SINGLE:
case XFS_IOC_FSBULKSTAT:
case XFS_IOC_FSINUMBERS:
arg = xfs_ioctl32_bulkstat(arg);
break;
#endif
case XFS_IOC_FSBULKSTAT_32:
case XFS_IOC_FSBULKSTAT_SINGLE_32:
case XFS_IOC_FSINUMBERS_32:
cmd = _NATIVE_IOC(cmd, struct xfs_fsop_bulkreq);
return xfs_ioc_bulkstat_compat(XFS_BHVTOI(VNHEAD(vp))->i_mount,
cmd, (void*)arg);
case XFS_IOC_FD_TO_HANDLE_32:
case XFS_IOC_PATH_TO_HANDLE_32:
case XFS_IOC_PATH_TO_FSHANDLE_32:
case XFS_IOC_OPEN_BY_HANDLE_32:
case XFS_IOC_READLINK_BY_HANDLE_32:
arg = xfs_ioctl32_fshandle(arg);
cmd = _NATIVE_IOC(cmd, struct xfs_fsop_handlereq);
break;
default:
return -ENOIOCTLCMD;
}

View File

@@ -123,6 +123,7 @@
#define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val
#define xfs_rotorstep xfs_params.rotorstep.val
#define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
#define xfs_fstrm_centisecs xfs_params.fstrm_timer.val
#define current_cpu() (raw_smp_processor_id())
#define current_pid() (current->pid)

View File

@@ -547,7 +547,8 @@ vfs_sync_worker(
if (!(vfsp->vfs_flag & VFS_RDONLY))
error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \
SYNC_ATTR | SYNC_REFCACHE, NULL);
SYNC_ATTR | SYNC_REFCACHE | SYNC_SUPER,
NULL);
vfsp->vfs_sync_seq++;
wake_up(&vfsp->vfs_wait_single_sync_task);
}
@@ -663,7 +664,7 @@ xfs_fs_sync_super(
* occur here so don't bother flushing the buftarg (i.e
* SYNC_QUIESCE) because it'll just get dirty again.
*/
flags = SYNC_FSDATA | SYNC_DELWRI | SYNC_WAIT | SYNC_IOWAIT;
flags = SYNC_DATA_QUIESCE;
} else
flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);

View File

@@ -210,6 +210,17 @@ static ctl_table xfs_table[] = {
.extra1 = &xfs_params.inherit_nodfrg.min,
.extra2 = &xfs_params.inherit_nodfrg.max
},
{
.ctl_name = XFS_FILESTREAM_TIMER,
.procname = "filestream_centisecs",
.data = &xfs_params.fstrm_timer.val,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.strategy = &sysctl_intvec,
.extra1 = &xfs_params.fstrm_timer.min,
.extra2 = &xfs_params.fstrm_timer.max,
},
/* please keep this the last entry */
#ifdef CONFIG_PROC_FS
{

View File

@@ -47,6 +47,7 @@ typedef struct xfs_param {
xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */
xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
xfs_sysctl_val_t fstrm_timer; /* Filestream dir-AG assoc'n timeout. */
} xfs_param_t;
/*
@@ -86,6 +87,7 @@ enum {
XFS_INHERIT_NOSYM = 19,
XFS_ROTORSTEP = 20,
XFS_INHERIT_NODFRG = 21,
XFS_FILESTREAM_TIMER = 22,
};
extern xfs_param_t xfs_params;

View File

@@ -92,6 +92,21 @@ typedef enum {
#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */
#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
#define SYNC_IOWAIT 0x0100 /* wait for all I/O to complete */
#define SYNC_SUPER 0x0200 /* flush superblock to disk */
/*
* When remounting a filesystem read-only or freezing the filesystem,
* we have two phases to execute. This first phase is syncing the data
* before we quiesce the fielsystem, and the second is flushing all the
* inodes out after we've waited for all the transactions created by
* the first phase to complete. The second phase uses SYNC_INODE_QUIESCE
* to ensure that the inodes are written to their location on disk
* rather than just existing in transactions in the log. This means
* after a quiesce there is no log replay required to write the inodes
* to disk (this is the main difference between a sync and a quiesce).
*/
#define SYNC_DATA_QUIESCE (SYNC_DELWRI|SYNC_FSDATA|SYNC_WAIT|SYNC_IOWAIT)
#define SYNC_INODE_QUIESCE (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT)
#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */
#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */

View File

@@ -129,10 +129,7 @@ typedef enum bhv_vchange {
VCHANGE_FLAGS_IOEXCL_COUNT = 4
} bhv_vchange_t;
typedef enum { L_FALSE, L_TRUE } lastclose_t;
typedef int (*vop_open_t)(bhv_desc_t *, struct cred *);
typedef int (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *);
typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *,
const struct iovec *, unsigned int,
loff_t *, int, struct cred *);
@@ -200,7 +197,6 @@ typedef int (*vop_iflush_t)(bhv_desc_t *, int);
typedef struct bhv_vnodeops {
bhv_position_t vn_position; /* position within behavior chain */
vop_open_t vop_open;
vop_close_t vop_close;
vop_read_t vop_read;
vop_write_t vop_write;
vop_splice_read_t vop_splice_read;
@@ -245,7 +241,6 @@ typedef struct bhv_vnodeops {
#define VNHEAD(vp) ((vp)->v_bh.bh_first)
#define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op)
#define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr)
#define bhv_vop_close(vp, f,last,cr) VOP(vop_close, vp)(VNHEAD(vp),f,last,cr)
#define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \
VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr)
#define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \

View File

@@ -62,10 +62,9 @@ uint ndquot;
kmem_zone_t *qm_dqzone;
kmem_zone_t *qm_dqtrxzone;
static kmem_shaker_t xfs_qm_shaker;
static struct shrinker *xfs_qm_shaker;
static cred_t xfs_zerocr;
static xfs_inode_t xfs_zeroino;
STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int);
STATIC void xfs_qm_list_destroy(xfs_dqlist_t *);
@@ -150,7 +149,7 @@ xfs_Gqm_init(void)
} else
xqm->qm_dqzone = qm_dqzone;
xfs_qm_shaker = kmem_shake_register(xfs_qm_shake);
xfs_qm_shaker = set_shrinker(DEFAULT_SEEKS, xfs_qm_shake);
/*
* The t_dqinfo portion of transactions.
@@ -182,7 +181,7 @@ xfs_qm_destroy(
ASSERT(xqm != NULL);
ASSERT(xqm->qm_nrefs == 0);
kmem_shake_deregister(xfs_qm_shaker);
remove_shrinker(xfs_qm_shaker);
hsize = xqm->qm_dqhashmask + 1;
for (i = 0; i < hsize; i++) {
xfs_qm_list_destroy(&(xqm->qm_usr_dqhtable[i]));
@@ -1415,7 +1414,7 @@ xfs_qm_qino_alloc(
return error;
}
if ((error = xfs_dir_ialloc(&tp, &xfs_zeroino, S_IFREG, 1, 0,
if ((error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0,
&xfs_zerocr, 0, 1, ip, &committed))) {
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
XFS_TRANS_ABORT);

View File

@@ -38,6 +38,7 @@
#define XFS_RW_TRACE 1
#define XFS_BUF_TRACE 1
#define XFS_VNODE_TRACE 1
#define XFS_FILESTREAMS_TRACE 1
#endif
#include <linux-2.6/xfs_linux.h>

View File

@@ -68,6 +68,7 @@ typedef struct xfs_agf {
__be32 agf_flcount; /* count of blocks in freelist */
__be32 agf_freeblks; /* total free blocks */
__be32 agf_longest; /* longest free space */
__be32 agf_btreeblks; /* # of blocks held in AGF btrees */
} xfs_agf_t;
#define XFS_AGF_MAGICNUM 0x00000001
@@ -81,7 +82,8 @@ typedef struct xfs_agf {
#define XFS_AGF_FLCOUNT 0x00000100
#define XFS_AGF_FREEBLKS 0x00000200
#define XFS_AGF_LONGEST 0x00000400
#define XFS_AGF_NUM_BITS 11
#define XFS_AGF_BTREEBLKS 0x00000800
#define XFS_AGF_NUM_BITS 12
#define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1)
/* disk block (xfs_daddr_t) in the AG */
@@ -186,12 +188,15 @@ typedef struct xfs_perag
__uint32_t pagf_flcount; /* count of blocks in freelist */
xfs_extlen_t pagf_freeblks; /* total free blocks */
xfs_extlen_t pagf_longest; /* longest free space */
__uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */
xfs_agino_t pagi_freecount; /* number of free inodes */
xfs_agino_t pagi_count; /* number of allocated inodes */
int pagb_count; /* pagb slots in use */
#ifdef __KERNEL__
lock_t pagb_lock; /* lock for pagb_list */
#endif
int pagb_count; /* pagb slots in use */
xfs_perag_busy_t *pagb_list; /* unstable blocks */
atomic_t pagf_fstrms; /* # of filestreams active in this AG */
} xfs_perag_t;
#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)

View File

@@ -55,17 +55,17 @@ xfs_alloc_search_busy(xfs_trans_t *tp,
ktrace_t *xfs_alloc_trace_buf;
#define TRACE_ALLOC(s,a) \
xfs_alloc_trace_alloc(fname, s, a, __LINE__)
xfs_alloc_trace_alloc(__FUNCTION__, s, a, __LINE__)
#define TRACE_FREE(s,a,b,x,f) \
xfs_alloc_trace_free(fname, s, mp, a, b, x, f, __LINE__)
xfs_alloc_trace_free(__FUNCTION__, s, mp, a, b, x, f, __LINE__)
#define TRACE_MODAGF(s,a,f) \
xfs_alloc_trace_modagf(fname, s, mp, a, f, __LINE__)
#define TRACE_BUSY(fname,s,ag,agb,l,sl,tp) \
xfs_alloc_trace_busy(fname, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSY, __LINE__)
#define TRACE_UNBUSY(fname,s,ag,sl,tp) \
xfs_alloc_trace_busy(fname, s, mp, ag, -1, -1, sl, tp, XFS_ALLOC_KTRACE_UNBUSY, __LINE__)
#define TRACE_BUSYSEARCH(fname,s,ag,agb,l,sl,tp) \
xfs_alloc_trace_busy(fname, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSYSEARCH, __LINE__)
xfs_alloc_trace_modagf(__FUNCTION__, s, mp, a, f, __LINE__)
#define TRACE_BUSY(__FUNCTION__,s,ag,agb,l,sl,tp) \
xfs_alloc_trace_busy(__FUNCTION__, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSY, __LINE__)
#define TRACE_UNBUSY(__FUNCTION__,s,ag,sl,tp) \
xfs_alloc_trace_busy(__FUNCTION__, s, mp, ag, -1, -1, sl, tp, XFS_ALLOC_KTRACE_UNBUSY, __LINE__)
#define TRACE_BUSYSEARCH(__FUNCTION__,s,ag,agb,l,sl,tp) \
xfs_alloc_trace_busy(__FUNCTION__, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSYSEARCH, __LINE__)
#else
#define TRACE_ALLOC(s,a)
#define TRACE_FREE(s,a,b,x,f)
@@ -420,7 +420,7 @@ xfs_alloc_read_agfl(
*/
STATIC void
xfs_alloc_trace_alloc(
char *name, /* function tag string */
const char *name, /* function tag string */
char *str, /* additional string */
xfs_alloc_arg_t *args, /* allocation argument structure */
int line) /* source line number */
@@ -453,7 +453,7 @@ xfs_alloc_trace_alloc(
*/
STATIC void
xfs_alloc_trace_free(
char *name, /* function tag string */
const char *name, /* function tag string */
char *str, /* additional string */
xfs_mount_t *mp, /* file system mount point */
xfs_agnumber_t agno, /* allocation group number */
@@ -479,7 +479,7 @@ xfs_alloc_trace_free(
*/
STATIC void
xfs_alloc_trace_modagf(
char *name, /* function tag string */
const char *name, /* function tag string */
char *str, /* additional string */
xfs_mount_t *mp, /* file system mount point */
xfs_agf_t *agf, /* new agf value */
@@ -507,7 +507,7 @@ xfs_alloc_trace_modagf(
STATIC void
xfs_alloc_trace_busy(
char *name, /* function tag string */
const char *name, /* function tag string */
char *str, /* additional string */
xfs_mount_t *mp, /* file system mount point */
xfs_agnumber_t agno, /* allocation group number */
@@ -549,9 +549,6 @@ xfs_alloc_ag_vextent(
xfs_alloc_arg_t *args) /* argument structure for allocation */
{
int error=0;
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_ag_vextent";
#endif
ASSERT(args->minlen > 0);
ASSERT(args->maxlen > 0);
@@ -635,9 +632,6 @@ xfs_alloc_ag_vextent_exact(
xfs_agblock_t fbno; /* start block of found extent */
xfs_agblock_t fend; /* end block of found extent */
xfs_extlen_t flen; /* length of found extent */
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_ag_vextent_exact";
#endif
int i; /* success/failure of operation */
xfs_agblock_t maxend; /* end of maximal extent */
xfs_agblock_t minend; /* end of minimal extent */
@@ -737,9 +731,6 @@ xfs_alloc_ag_vextent_near(
xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */
xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */
xfs_btree_cur_t *cnt_cur; /* cursor for count btree */
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_ag_vextent_near";
#endif
xfs_agblock_t gtbno; /* start bno of right side entry */
xfs_agblock_t gtbnoa; /* aligned ... */
xfs_extlen_t gtdiff; /* difference to right side entry */
@@ -1270,9 +1261,6 @@ xfs_alloc_ag_vextent_size(
int error; /* error result */
xfs_agblock_t fbno; /* start of found freespace */
xfs_extlen_t flen; /* length of found freespace */
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_ag_vextent_size";
#endif
int i; /* temp status variable */
xfs_agblock_t rbno; /* returned block number */
xfs_extlen_t rlen; /* length of returned extent */
@@ -1427,9 +1415,6 @@ xfs_alloc_ag_vextent_small(
int error;
xfs_agblock_t fbno;
xfs_extlen_t flen;
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_ag_vextent_small";
#endif
int i;
if ((error = xfs_alloc_decrement(ccur, 0, &i)))
@@ -1447,7 +1432,8 @@ xfs_alloc_ag_vextent_small(
else if (args->minlen == 1 && args->alignment == 1 && !args->isfl &&
(be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
> args->minleft)) {
if ((error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno)))
error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
if (error)
goto error0;
if (fbno != NULLAGBLOCK) {
if (args->userdata) {
@@ -1515,9 +1501,6 @@ xfs_free_ag_extent(
xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */
xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */
int error; /* error return value */
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_free_ag_extent";
#endif
xfs_agblock_t gtbno; /* start of right neighbor block */
xfs_extlen_t gtlen; /* length of right neighbor block */
int haveleft; /* have a left neighbor block */
@@ -1923,7 +1906,8 @@ xfs_alloc_fix_freelist(
while (be32_to_cpu(agf->agf_flcount) > need) {
xfs_buf_t *bp;
if ((error = xfs_alloc_get_freelist(tp, agbp, &bno)))
error = xfs_alloc_get_freelist(tp, agbp, &bno, 0);
if (error)
return error;
if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1)))
return error;
@@ -1973,8 +1957,9 @@ xfs_alloc_fix_freelist(
* Put each allocated block on the list.
*/
for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) {
if ((error = xfs_alloc_put_freelist(tp, agbp, agflbp,
bno)))
error = xfs_alloc_put_freelist(tp, agbp,
agflbp, bno, 0);
if (error)
return error;
}
}
@@ -1991,16 +1976,15 @@ int /* error */
xfs_alloc_get_freelist(
xfs_trans_t *tp, /* transaction pointer */
xfs_buf_t *agbp, /* buffer containing the agf structure */
xfs_agblock_t *bnop) /* block address retrieved from freelist */
xfs_agblock_t *bnop, /* block address retrieved from freelist */
int btreeblk) /* destination is a AGF btree */
{
xfs_agf_t *agf; /* a.g. freespace structure */
xfs_agfl_t *agfl; /* a.g. freelist structure */
xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */
xfs_agblock_t bno; /* block number returned */
int error;
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_get_freelist";
#endif
int logflags;
xfs_mount_t *mp; /* mount structure */
xfs_perag_t *pag; /* per allocation group data */
@@ -2032,8 +2016,16 @@ xfs_alloc_get_freelist(
be32_add(&agf->agf_flcount, -1);
xfs_trans_agflist_delta(tp, -1);
pag->pagf_flcount--;
TRACE_MODAGF(NULL, agf, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT);
xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT);
logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
if (btreeblk) {
be32_add(&agf->agf_btreeblks, 1);
pag->pagf_btreeblks++;
logflags |= XFS_AGF_BTREEBLKS;
}
TRACE_MODAGF(NULL, agf, logflags);
xfs_alloc_log_agf(tp, agbp, logflags);
*bnop = bno;
/*
@@ -2071,6 +2063,7 @@ xfs_alloc_log_agf(
offsetof(xfs_agf_t, agf_flcount),
offsetof(xfs_agf_t, agf_freeblks),
offsetof(xfs_agf_t, agf_longest),
offsetof(xfs_agf_t, agf_btreeblks),
sizeof(xfs_agf_t)
};
@@ -2106,15 +2099,14 @@ xfs_alloc_put_freelist(
xfs_trans_t *tp, /* transaction pointer */
xfs_buf_t *agbp, /* buffer for a.g. freelist header */
xfs_buf_t *agflbp,/* buffer for a.g. free block array */
xfs_agblock_t bno) /* block being freed */
xfs_agblock_t bno, /* block being freed */
int btreeblk) /* block came from a AGF btree */
{
xfs_agf_t *agf; /* a.g. freespace structure */
xfs_agfl_t *agfl; /* a.g. free block array */
__be32 *blockp;/* pointer to array entry */
int error;
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_put_freelist";
#endif
int logflags;
xfs_mount_t *mp; /* mount structure */
xfs_perag_t *pag; /* per allocation group data */
@@ -2132,11 +2124,22 @@ xfs_alloc_put_freelist(
be32_add(&agf->agf_flcount, 1);
xfs_trans_agflist_delta(tp, 1);
pag->pagf_flcount++;
logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
if (btreeblk) {
be32_add(&agf->agf_btreeblks, -1);
pag->pagf_btreeblks--;
logflags |= XFS_AGF_BTREEBLKS;
}
TRACE_MODAGF(NULL, agf, logflags);
xfs_alloc_log_agf(tp, agbp, logflags);
ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)];
*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);
TRACE_MODAGF(NULL, agf, logflags);
xfs_alloc_log_agf(tp, agbp, logflags);
xfs_trans_log_buf(tp, agflbp,
(int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl),
(int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl +
@@ -2196,6 +2199,7 @@ xfs_alloc_read_agf(
pag = &mp->m_perag[agno];
if (!pag->pagf_init) {
pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
pag->pagf_longest = be32_to_cpu(agf->agf_longest);
pag->pagf_levels[XFS_BTNUM_BNOi] =
@@ -2235,9 +2239,6 @@ xfs_alloc_vextent(
xfs_agblock_t agsize; /* allocation group size */
int error;
int flags; /* XFS_ALLOC_FLAG_... locking flags */
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_vextent";
#endif
xfs_extlen_t minleft;/* minimum left value, temp copy */
xfs_mount_t *mp; /* mount structure pointer */
xfs_agnumber_t sagno; /* starting allocation group number */

View File

@@ -136,7 +136,8 @@ int /* error */
xfs_alloc_get_freelist(
struct xfs_trans *tp, /* transaction pointer */
struct xfs_buf *agbp, /* buffer containing the agf structure */
xfs_agblock_t *bnop); /* block address retrieved from freelist */
xfs_agblock_t *bnop, /* block address retrieved from freelist */
int btreeblk); /* destination is a AGF btree */
/*
* Log the given fields from the agf structure.
@@ -165,7 +166,8 @@ xfs_alloc_put_freelist(
struct xfs_trans *tp, /* transaction pointer */
struct xfs_buf *agbp, /* buffer for a.g. freelist header */
struct xfs_buf *agflbp,/* buffer for a.g. free block array */
xfs_agblock_t bno); /* block being freed */
xfs_agblock_t bno, /* block being freed */
int btreeblk); /* owner was a AGF btree */
/*
* Read in the allocation group header (free/alloc section).

Some files were not shown because too many files have changed in this diff Show More