Commit 958b7f37 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://oss.sgi.com:8090/xfs/xfs-2.6

* git://oss.sgi.com:8090/xfs/xfs-2.6: (33 commits)
  [XFS] Don't use kmap in xfs_iozero.
  [XFS] Remove a bunch of unused functions from XFS.
  [XFS] Remove unused arguments from the XFS_BTREE_*_ADDR macros.
  [XFS] Remove unused header files for MAC and CAP checking functionality.
  [XFS] Make freeze code a little cleaner.
  [XFS] Remove unused argument to xfs_bmap_finish
  [XFS] Clean up use of VFS attr flags
  [XFS] Remove useless memory barrier
  [XFS] XFS sysctl cleanups
  [XFS] Fix assertion in xfs_attr_shortform_remove().
  [XFS] Fix callers of xfs_iozero() to zero the correct range.
  [XFS] Ensure a frozen filesystem has a clean log before writing the dummy
  [XFS] Fix sub-block zeroing for buffered writes into unwritten extents.
  [XFS] Re-initialize the per-cpu superblock counters after recovery.
  [XFS] Fix block reservation changes for non-SMP systems.
  [XFS] Fix block reservation mechanism.
  [XFS] Make growfs work for amounts greater than 2TB
  [XFS] Fix inode log item use-after-free on forced shutdown
  [XFS] Fix attr2 corruption with btree data extents
  [XFS] Workaround log space issue by increasing XFS_TRANS_PUSH_AIL_RESTARTS
  ...
parents d6879837 e7ff6aed
......@@ -31,15 +31,13 @@ typedef struct {
do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
#define mrlock_init(mrp, t,n,s) mrinit(mrp, n)
#define mrfree(mrp) do { } while (0)
#define mraccess(mrp) mraccessf(mrp, 0)
#define mrupdate(mrp) mrupdatef(mrp, 0)
static inline void mraccessf(mrlock_t *mrp, int flags)
static inline void mraccess(mrlock_t *mrp)
{
down_read(&mrp->mr_lock);
}
static inline void mrupdatef(mrlock_t *mrp, int flags)
static inline void mrupdate(mrlock_t *mrp)
{
down_write(&mrp->mr_lock);
mrp->mr_writer = 1;
......
......@@ -249,7 +249,7 @@ xfs_map_blocks(
return -error;
}
STATIC inline int
STATIC_INLINE int
xfs_iomap_valid(
xfs_iomap_t *iomapp,
loff_t offset)
......@@ -1283,13 +1283,18 @@ __xfs_get_blocks(
bh_result->b_bdev = iomap.iomap_target->bt_bdev;
/*
* If we previously allocated a block out beyond eof and we are
* now coming back to use it then we will need to flag it as new
* even if it has a disk address.
* If we previously allocated a block out beyond eof and we are now
* coming back to use it then we will need to flag it as new even if it
* has a disk address.
*
* With sub-block writes into unwritten extents we also need to mark
* the buffer as new so that the unwritten parts of the buffer gets
* correctly zeroed.
*/
if (create &&
((!buffer_mapped(bh_result) && !buffer_uptodate(bh_result)) ||
(offset >= i_size_read(inode)) || (iomap.iomap_flags & IOMAP_NEW)))
(offset >= i_size_read(inode)) ||
(iomap.iomap_flags & (IOMAP_NEW|IOMAP_UNWRITTEN))))
set_buffer_new(bh_result);
if (iomap.iomap_flags & IOMAP_DELAY) {
......
......@@ -34,13 +34,13 @@
#include <linux/backing-dev.h>
#include <linux/freezer.h>
STATIC kmem_zone_t *xfs_buf_zone;
STATIC kmem_shaker_t xfs_buf_shake;
static kmem_zone_t *xfs_buf_zone;
static kmem_shaker_t xfs_buf_shake;
STATIC int xfsbufd(void *);
STATIC int xfsbufd_wakeup(int, gfp_t);
STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int);
STATIC struct workqueue_struct *xfslogd_workqueue;
static struct workqueue_struct *xfslogd_workqueue;
struct workqueue_struct *xfsdatad_workqueue;
#ifdef XFS_BUF_TRACE
......@@ -139,7 +139,7 @@ page_region_mask(
return mask;
}
STATIC inline void
STATIC_INLINE void
set_page_region(
struct page *page,
size_t offset,
......@@ -151,7 +151,7 @@ set_page_region(
SetPageUptodate(page);
}
STATIC inline int
STATIC_INLINE int
test_page_region(
struct page *page,
size_t offset,
......@@ -171,9 +171,9 @@ typedef struct a_list {
struct a_list *next;
} a_list_t;
STATIC a_list_t *as_free_head;
STATIC int as_list_len;
STATIC DEFINE_SPINLOCK(as_lock);
static a_list_t *as_free_head;
static int as_list_len;
static DEFINE_SPINLOCK(as_lock);
/*
* Try to batch vunmaps because they are costly.
......@@ -1085,7 +1085,7 @@ xfs_buf_iostart(
return status;
}
STATIC __inline__ int
STATIC_INLINE int
_xfs_buf_iolocked(
xfs_buf_t *bp)
{
......@@ -1095,7 +1095,7 @@ _xfs_buf_iolocked(
return 0;
}
STATIC __inline__ void
STATIC_INLINE void
_xfs_buf_ioend(
xfs_buf_t *bp,
int schedule)
......@@ -1426,8 +1426,8 @@ xfs_free_bufhash(
/*
* buftarg list for delwrite queue processing
*/
STATIC LIST_HEAD(xfs_buftarg_list);
STATIC DEFINE_SPINLOCK(xfs_buftarg_lock);
LIST_HEAD(xfs_buftarg_list);
static DEFINE_SPINLOCK(xfs_buftarg_lock);
STATIC void
xfs_register_buftarg(
......@@ -1679,21 +1679,60 @@ xfsbufd_wakeup(
return 0;
}
/*
* Move as many buffers as specified to the supplied list
* idicating if we skipped any buffers to prevent deadlocks.
*/
STATIC int
xfs_buf_delwri_split(
xfs_buftarg_t *target,
struct list_head *list,
unsigned long age)
{
xfs_buf_t *bp, *n;
struct list_head *dwq = &target->bt_delwrite_queue;
spinlock_t *dwlk = &target->bt_delwrite_lock;
int skipped = 0;
int force;
force = test_and_clear_bit(XBT_FORCE_FLUSH, &target->bt_flags);
INIT_LIST_HEAD(list);
spin_lock(dwlk);
list_for_each_entry_safe(bp, n, dwq, b_list) {
XB_TRACE(bp, "walkq1", (long)xfs_buf_ispin(bp));
ASSERT(bp->b_flags & XBF_DELWRI);
if (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) {
if (!force &&
time_before(jiffies, bp->b_queuetime + age)) {
xfs_buf_unlock(bp);
break;
}
bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|
_XBF_RUN_QUEUES);
bp->b_flags |= XBF_WRITE;
list_move_tail(&bp->b_list, list);
} else
skipped++;
}
spin_unlock(dwlk);
return skipped;
}
STATIC int
xfsbufd(
void *data)
void *data)
{
struct list_head tmp;
unsigned long age;
xfs_buftarg_t *target = (xfs_buftarg_t *)data;
xfs_buf_t *bp, *n;
struct list_head *dwq = &target->bt_delwrite_queue;
spinlock_t *dwlk = &target->bt_delwrite_lock;
int count;
struct list_head tmp;
xfs_buftarg_t *target = (xfs_buftarg_t *)data;
int count;
xfs_buf_t *bp;
current->flags |= PF_MEMALLOC;
INIT_LIST_HEAD(&tmp);
do {
if (unlikely(freezing(current))) {
set_bit(XBT_FORCE_SLEEP, &target->bt_flags);
......@@ -1705,37 +1744,17 @@ 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) {
XB_TRACE(bp, "walkq1", (long)xfs_buf_ispin(bp));
ASSERT(bp->b_flags & XBF_DELWRI);
if (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) {
if (!test_bit(XBT_FORCE_FLUSH,
&target->bt_flags) &&
time_before(jiffies,
bp->b_queuetime + age)) {
xfs_buf_unlock(bp);
break;
}
bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|
_XBF_RUN_QUEUES);
bp->b_flags |= XBF_WRITE;
list_move_tail(&bp->b_list, &tmp);
count++;
}
}
spin_unlock(dwlk);
xfs_buf_delwri_split(target, &tmp,
xfs_buf_age_centisecs * msecs_to_jiffies(10));
count = 0;
while (!list_empty(&tmp)) {
bp = list_entry(tmp.next, xfs_buf_t, b_list);
ASSERT(target == bp->b_target);
list_del_init(&bp->b_list);
xfs_buf_iostrategy(bp);
count++;
}
if (as_list_len > 0)
......@@ -1743,7 +1762,6 @@ xfsbufd(
if (count)
blk_run_address_space(target->bt_mapping);
clear_bit(XBT_FORCE_FLUSH, &target->bt_flags);
} while (!kthread_should_stop());
return 0;
......@@ -1756,40 +1774,24 @@ xfsbufd(
*/
int
xfs_flush_buftarg(
xfs_buftarg_t *target,
int wait)
xfs_buftarg_t *target,
int wait)
{
struct list_head tmp;
xfs_buf_t *bp, *n;
int pincount = 0;
struct list_head *dwq = &target->bt_delwrite_queue;
spinlock_t *dwlk = &target->bt_delwrite_lock;
struct list_head tmp;
xfs_buf_t *bp, *n;
int pincount = 0;
xfs_buf_runall_queues(xfsdatad_workqueue);
xfs_buf_runall_queues(xfslogd_workqueue);
INIT_LIST_HEAD(&tmp);
spin_lock(dwlk);
list_for_each_entry_safe(bp, n, dwq, b_list) {
ASSERT(bp->b_target == target);
ASSERT(bp->b_flags & (XBF_DELWRI | _XBF_DELWRI_Q));
XB_TRACE(bp, "walkq2", (long)xfs_buf_ispin(bp));
if (xfs_buf_ispin(bp)) {
pincount++;
continue;
}
list_move_tail(&bp->b_list, &tmp);
}
spin_unlock(dwlk);
set_bit(XBT_FORCE_FLUSH, &target->bt_flags);
pincount = xfs_buf_delwri_split(target, &tmp, 0);
/*
* Dropped the delayed write list lock, now walk the temporary list
*/
list_for_each_entry_safe(bp, n, &tmp, b_list) {
xfs_buf_lock(bp);
bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q|_XBF_RUN_QUEUES);
bp->b_flags |= XBF_WRITE;
ASSERT(target == bp->b_target);
if (wait)
bp->b_flags &= ~XBF_ASYNC;
else
......
......@@ -69,8 +69,8 @@ typedef enum {
} xfs_buf_flags_t;
typedef enum {
XBT_FORCE_SLEEP = (0 << 1),
XBT_FORCE_FLUSH = (1 << 1),
XBT_FORCE_SLEEP = 0,
XBT_FORCE_FLUSH = 1,
} xfs_buftarg_flags_t;
typedef struct xfs_bufhash {
......
......@@ -24,7 +24,7 @@
#include "xfs_mount.h"
#include "xfs_export.h"
STATIC struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
/*
* XFS encodes and decodes the fileid portion of NFS filehandles
......
......@@ -46,7 +46,7 @@ static struct vm_operations_struct xfs_file_vm_ops;
static struct vm_operations_struct xfs_dmapi_file_vm_ops;
#endif
STATIC inline ssize_t
STATIC_INLINE ssize_t
__xfs_file_read(
struct kiocb *iocb,
const struct iovec *iov,
......@@ -84,7 +84,7 @@ xfs_file_aio_read_invis(
return __xfs_file_read(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
}
STATIC inline ssize_t
STATIC_INLINE ssize_t
__xfs_file_write(
struct kiocb *iocb,
const struct iovec *iov,
......
......@@ -41,8 +41,6 @@
#include "xfs_error.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
#include "xfs_attr.h"
#include "xfs_bmap.h"
#include "xfs_buf_item.h"
......@@ -355,7 +353,6 @@ STATIC int
xfs_readlink_by_handle(
xfs_mount_t *mp,
void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
int error;
......@@ -388,7 +385,7 @@ xfs_readlink_by_handle(
aiov.iov_len = olen;
aiov.iov_base = hreq.ohandle;
auio.uio_iov = &aiov;
auio.uio_iov = (struct kvec *)&aiov;
auio.uio_iovcnt = 1;
auio.uio_offset = 0;
auio.uio_segflg = UIO_USERSPACE;
......@@ -406,7 +403,6 @@ STATIC int
xfs_fssetdm_by_handle(
xfs_mount_t *mp,
void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
int error;
......@@ -448,7 +444,6 @@ STATIC int
xfs_attrlist_by_handle(
xfs_mount_t *mp,
void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
int error;
......@@ -569,7 +564,6 @@ STATIC int
xfs_attrmulti_by_handle(
xfs_mount_t *mp,
void __user *arg,
struct file *parfilp,
struct inode *parinode)
{
int error;
......@@ -689,7 +683,6 @@ xfs_ioc_xattr(
STATIC int
xfs_ioc_getbmap(
bhv_desc_t *bdp,
struct file *filp,
int flags,
unsigned int cmd,
void __user *arg);
......@@ -788,7 +781,7 @@ xfs_ioctl(
case XFS_IOC_GETBMAP:
case XFS_IOC_GETBMAPA:
return xfs_ioc_getbmap(bdp, filp, ioflags, cmd, arg);
return xfs_ioc_getbmap(bdp, ioflags, cmd, arg);
case XFS_IOC_GETBMAPX:
return xfs_ioc_getbmapx(bdp, arg);
......@@ -802,16 +795,16 @@ xfs_ioctl(
return xfs_open_by_handle(mp, arg, filp, inode);
case XFS_IOC_FSSETDM_BY_HANDLE:
return xfs_fssetdm_by_handle(mp, arg, filp, inode);
return xfs_fssetdm_by_handle(mp, arg, inode);
case XFS_IOC_READLINK_BY_HANDLE:
return xfs_readlink_by_handle(mp, arg, filp, inode);
return xfs_readlink_by_handle(mp, arg, inode);
case XFS_IOC_ATTRLIST_BY_HANDLE:
return xfs_attrlist_by_handle(mp, arg, filp, inode);
return xfs_attrlist_by_handle(mp, arg, inode);
case XFS_IOC_ATTRMULTI_BY_HANDLE:
return xfs_attrmulti_by_handle(mp, arg, filp, inode);
return xfs_attrmulti_by_handle(mp, arg, inode);
case XFS_IOC_SWAPEXT: {
error = xfs_swapext((struct xfs_swapext __user *)arg);
......@@ -1095,11 +1088,6 @@ xfs_ioc_fsgeometry(
/*
* Linux extended inode flags interface.
*/
#define LINUX_XFLAG_SYNC 0x00000008 /* Synchronous updates */
#define LINUX_XFLAG_IMMUTABLE 0x00000010 /* Immutable file */
#define LINUX_XFLAG_APPEND 0x00000020 /* writes to file may only append */
#define LINUX_XFLAG_NODUMP 0x00000040 /* do not dump file */
#define LINUX_XFLAG_NOATIME 0x00000080 /* do not update atime */
STATIC unsigned int
xfs_merge_ioc_xflags(
......@@ -1108,23 +1096,23 @@ xfs_merge_ioc_xflags(
{
unsigned int xflags = start;
if (flags & LINUX_XFLAG_IMMUTABLE)
if (flags & FS_IMMUTABLE_FL)
xflags |= XFS_XFLAG_IMMUTABLE;
else
xflags &= ~XFS_XFLAG_IMMUTABLE;
if (flags & LINUX_XFLAG_APPEND)
if (flags & FS_APPEND_FL)
xflags |= XFS_XFLAG_APPEND;
else
xflags &= ~XFS_XFLAG_APPEND;
if (flags & LINUX_XFLAG_SYNC)
if (flags & FS_SYNC_FL)
xflags |= XFS_XFLAG_SYNC;
else
xflags &= ~XFS_XFLAG_SYNC;
if (flags & LINUX_XFLAG_NOATIME)
if (flags & FS_NOATIME_FL)
xflags |= XFS_XFLAG_NOATIME;
else
xflags &= ~XFS_XFLAG_NOATIME;
if (flags & LINUX_XFLAG_NODUMP)
if (flags & FS_NODUMP_FL)
xflags |= XFS_XFLAG_NODUMP;
else
xflags &= ~XFS_XFLAG_NODUMP;
......@@ -1139,15 +1127,15 @@ xfs_di2lxflags(
unsigned int flags = 0;
if (di_flags & XFS_DIFLAG_IMMUTABLE)
flags |= LINUX_XFLAG_IMMUTABLE;
flags |= FS_IMMUTABLE_FL;
if (di_flags & XFS_DIFLAG_APPEND)
flags |= LINUX_XFLAG_APPEND;
flags |= FS_APPEND_FL;
if (di_flags & XFS_DIFLAG_SYNC)
flags |= LINUX_XFLAG_SYNC;
flags |= FS_SYNC_FL;
if (di_flags & XFS_DIFLAG_NOATIME)
flags |= LINUX_XFLAG_NOATIME;
flags |= FS_NOATIME_FL;
if (di_flags & XFS_DIFLAG_NODUMP)
flags |= LINUX_XFLAG_NODUMP;
flags |= FS_NODUMP_FL;
return flags;
}
......@@ -1247,9 +1235,9 @@ xfs_ioc_xattr(
break;
}
if (flags & ~(LINUX_XFLAG_IMMUTABLE | LINUX_XFLAG_APPEND | \
LINUX_XFLAG_NOATIME | LINUX_XFLAG_NODUMP | \
LINUX_XFLAG_SYNC)) {
if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
FS_NOATIME_FL | FS_NODUMP_FL | \
FS_SYNC_FL)) {
error = -EOPNOTSUPP;
break;
}
......@@ -1281,7 +1269,6 @@ xfs_ioc_xattr(
STATIC int
xfs_ioc_getbmap(
bhv_desc_t *bdp,
struct file *filp,
int ioflags,
unsigned int cmd,
void __user *arg)
......
......@@ -43,8 +43,6 @@
#include "xfs_itable.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
......@@ -250,13 +248,13 @@ xfs_init_security(
*
* XXX(hch): nfsd is broken, better fix it instead.
*/
STATIC inline int
STATIC_INLINE int
xfs_has_fs_struct(struct task_struct *task)
{
return (task->fs != init_task.fs);
}
STATIC inline void
STATIC void
xfs_cleanup_inode(
bhv_vnode_t *dvp,
bhv_vnode_t *vp,
......
......@@ -43,8 +43,6 @@
#include "xfs_itable.h"
#include "xfs_rw.h"
#include "xfs_acl.h"
#include "xfs_cap.h"
#include "xfs_mac.h"
#include "xfs_attr.h"
#include "xfs_inode_item.h"
#include "xfs_buf_item.h"
......@@ -134,13 +132,11 @@ STATIC int
xfs_iozero(
struct inode *ip, /* inode */
loff_t pos, /* offset in file */
size_t count, /* size of data to zero */
loff_t end_size) /* max file size to set */
size_t count) /* size of data to zero */
{
unsigned bytes;
struct page *page;
struct address_space *mapping;
char *kaddr;
int status;
mapping = ip->i_mapping;
......@@ -158,26 +154,21 @@ xfs_iozero(
if (!page)
break;
kaddr = kmap(page);
status = mapping->a_ops->prepare_write(NULL, page, offset,
offset + bytes);
if (status) {
if (status)
goto unlock;
}
memset((void *) (kaddr + offset), 0, bytes);
flush_dcache_page(page);
memclear_highpage_flush(page, offset, bytes);
status = mapping->a_ops->commit_write(NULL, page, offset,
offset + bytes);
if (!status) {
pos += bytes;
count -= bytes;
if (pos > i_size_read(ip))
i_size_write(ip, pos < end_size ? pos : end_size);
}
unlock:
kunmap(page);
unlock_page(page);
page_cache_release(page);
if (status)
......@@ -449,8 +440,8 @@ STATIC int /* error (positive) */
xfs_zero_last_block(
struct inode *ip,
xfs_iocore_t *io,
xfs_fsize_t isize,
xfs_fsize_t end_size)
xfs_fsize_t offset,
xfs_fsize_t isize)
{
xfs_fileoff_t last_fsb;
xfs_mount_t *mp = io->io_mount;
......@@ -459,7 +450,6 @@ xfs_zero_last_block(
int zero_len;
int error = 0;
xfs_bmbt_irec_t imap;
loff_t loff;
ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0);
......@@ -494,9 +484,10 @@ xfs_zero_last_block(
*/
XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
loff = XFS_FSB_TO_B(mp, last_fsb);
zero_len = mp->m_sb.sb_blocksize - zero_offset;
error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size);
if (isize + zero_len > offset)
zero_len = offset - isize;
error = xfs_iozero(ip, isize, zero_len);
XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZ