Freezer: make kernel threads nonfreezable by default
[safe/jmp/linux-2.6] / fs / xfs / linux-2.6 / xfs_super.c
index b7aad3c..4528f9a 100644 (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
@@ -23,7 +23,6 @@
 #include "xfs_trans.h"
 #include "xfs_sb.h"
 #include "xfs_ag.h"
-#include "xfs_dir.h"
 #include "xfs_dir2.h"
 #include "xfs_alloc.h"
 #include "xfs_dmapi.h"
@@ -32,7 +31,6 @@
 #include "xfs_bmap_btree.h"
 #include "xfs_alloc_btree.h"
 #include "xfs_ialloc_btree.h"
-#include "xfs_dir_sf.h"
 #include "xfs_dir2_sf.h"
 #include "xfs_attr_sf.h"
 #include "xfs_dinode.h"
@@ -45,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"
 #include <linux/mempool.h>
 #include <linux/writeback.h>
 #include <linux/kthread.h>
+#include <linux/freezer.h>
 
-STATIC struct quotactl_ops xfs_quotactl_operations;
-STATIC struct super_operations xfs_super_operations;
-STATIC kmem_zone_t *xfs_vnode_zone;
-STATIC kmem_zone_t *xfs_ioend_zone;
+static struct quotactl_ops xfs_quotactl_operations;
+static struct super_operations xfs_super_operations;
+static kmem_zone_t *xfs_vnode_zone;
+static kmem_zone_t *xfs_ioend_zone;
 mempool_t *xfs_ioend_pool;
 
 STATIC struct xfs_mount_args *
@@ -122,7 +119,7 @@ xfs_max_file_offset(
        return (((__uint64_t)pagefactor) << bitshift) - 1;
 }
 
-STATIC __inline__ void
+STATIC_INLINE void
 xfs_set_inodeops(
        struct inode            *inode)
 {
@@ -148,7 +145,7 @@ xfs_set_inodeops(
        }
 }
 
-STATIC __inline__ void
+STATIC_INLINE void
 xfs_revalidate_inode(
        xfs_mount_t             *mp,
        bhv_vnode_t             *vp,
@@ -173,7 +170,6 @@ xfs_revalidate_inode(
                break;
        }
 
-       inode->i_blksize = xfs_preferred_iosize(mp);
        inode->i_generation = ip->i_d.di_gen;
        i_size_write(inode, ip->i_d.di_size);
        inode->i_blocks =
@@ -230,7 +226,7 @@ xfs_initialize_vnode(
                xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
                xfs_set_inodeops(inode);
 
-               ip->i_flags &= ~XFS_INEW;
+               xfs_iflags_clear(ip, XFS_INEW);
                barrier();
 
                unlock_new_inode(inode);
@@ -316,6 +312,13 @@ xfs_mountfs_check_barriers(xfs_mount_t *mp)
                return;
        }
 
+       if (xfs_readonly_buftarg(mp->m_ddev_targp)) {
+               xfs_fs_cmn_err(CE_NOTE, mp,
+                 "Disabling barriers, underlying device is readonly");
+               mp->m_flags &= ~XFS_MOUNT_BARRIER;
+               return;
+       }
+
        error = xfs_barrier_test(mp);
        if (error) {
                xfs_fs_cmn_err(CE_NOTE, mp,
@@ -357,9 +360,7 @@ xfs_fs_inode_init_once(
        kmem_zone_t             *zonep,
        unsigned long           flags)
 {
-       if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-                     SLAB_CTOR_CONSTRUCTOR)
-               inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
+       inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
 }
 
 STATIC int
@@ -546,9 +547,9 @@ 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++;
-       wmb();
        wake_up(&vfsp->vfs_wait_single_sync_task);
 }
 
@@ -561,6 +562,7 @@ xfssyncd(
        bhv_vfs_sync_work_t     *work, *n;
        LIST_HEAD               (tmp);
 
+       set_freezable();
        timeleft = xfs_syncd_centisecs * msecs_to_jiffies(10);
        for (;;) {
                timeleft = schedule_timeout_interruptible(timeleft);
@@ -654,9 +656,17 @@ xfs_fs_sync_super(
        int                     error;
        int                     flags;
 
-       if (unlikely(sb->s_frozen == SB_FREEZE_WRITE))
-               flags = SYNC_QUIESCE;
-       else
+       if (unlikely(sb->s_frozen == SB_FREEZE_WRITE)) {
+               /*
+                * First stage of freeze - no more writers will make progress
+                * now we are here, so we flush delwri and delalloc buffers
+                * here, then wait for all I/O to complete.  Data is frozen at
+                * that point. Metadata is not frozen, transactions can still
+                * occur here so don't bother flushing the buftarg (i.e
+                * SYNC_QUIESCE) because it'll just get dirty again.
+                */
+               flags = SYNC_DATA_QUIESCE;
+       } else
                flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0);
 
        error = bhv_vfs_sync(vfsp, flags, NULL);
@@ -686,10 +696,11 @@ xfs_fs_sync_super(
 
 STATIC int
 xfs_fs_statfs(
-       struct super_block      *sb,
+       struct dentry           *dentry,
        struct kstatfs          *statp)
 {
-       return -bhv_vfs_statvfs(vfs_from_sb(sb), statp, NULL);
+       return -bhv_vfs_statvfs(vfs_from_sb(dentry->d_sb), statp,
+                               vn_from_inode(dentry->d_inode));
 }
 
 STATIC int
@@ -796,9 +807,7 @@ xfs_fs_fill_super(
        }
 
        sb_min_blocksize(sb, BBSIZE);
-#ifdef CONFIG_XFS_EXPORT
        sb->s_export_op = &xfs_export_operations;
-#endif
        sb->s_qcop = &xfs_quotactl_operations;
        sb->s_op = &xfs_super_operations;
 
@@ -857,17 +866,19 @@ fail_vfsop:
        return -error;
 }
 
-STATIC struct super_block *
+STATIC int
 xfs_fs_get_sb(
        struct file_system_type *fs_type,
        int                     flags,
        const char              *dev_name,
-       void                    *data)
+       void                    *data,
+       struct vfsmount         *mnt)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super);
+       return get_sb_bdev(fs_type, flags, dev_name, data, xfs_fs_fill_super,
+                          mnt);
 }
 
-STATIC struct super_operations xfs_super_operations = {
+static struct super_operations xfs_super_operations = {
        .alloc_inode            = xfs_fs_alloc_inode,
        .destroy_inode          = xfs_fs_destroy_inode,
        .write_inode            = xfs_fs_write_inode,
@@ -881,7 +892,7 @@ STATIC struct super_operations xfs_super_operations = {
        .show_options           = xfs_fs_show_options,
 };
 
-STATIC struct quotactl_ops xfs_quotactl_operations = {
+static struct quotactl_ops xfs_quotactl_operations = {
        .quota_sync             = xfs_fs_quotasync,
        .get_xstate             = xfs_fs_getxstate,
        .set_xstate             = xfs_fs_setxstate,
@@ -889,7 +900,7 @@ STATIC struct quotactl_ops xfs_quotactl_operations = {
        .set_xquota             = xfs_fs_setxquota,
 };
 
-STATIC struct file_system_type xfs_fs_type = {
+static struct file_system_type xfs_fs_type = {
        .owner                  = THIS_MODULE,
        .name                   = "xfs",
        .get_sb                 = xfs_fs_get_sb,