Merge tag 'driver-core-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / fs / xfs / xfs_mount.c
index 56e85a6..b341f10 100644 (file)
@@ -43,6 +43,8 @@
 #include "xfs_icache.h"
 #include "xfs_sysfs.h"
 #include "xfs_rmap_btree.h"
+#include "xfs_refcount_btree.h"
+#include "xfs_reflink.h"
 
 
 static DEFINE_MUTEX(xfs_uuid_table_mutex);
@@ -684,6 +686,7 @@ xfs_mountfs(
        xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
        xfs_ialloc_compute_maxlevels(mp);
        xfs_rmapbt_compute_maxlevels(mp);
+       xfs_refcountbt_compute_maxlevels(mp);
 
        xfs_set_maxicount(mp);
 
@@ -922,6 +925,15 @@ xfs_mountfs(
                }
        }
 
+       /*
+        * During the second phase of log recovery, we need iget and
+        * iput to behave like they do for an active filesystem.
+        * xfs_fs_drop_inode needs to be able to prevent the deletion
+        * of inodes before we're done replaying log items on those
+        * inodes.
+        */
+       mp->m_super->s_flags |= MS_ACTIVE;
+
        /*
         * Finish recovering the file system.  This part needed to be delayed
         * until after the root and real-time bitmap inodes were consistently
@@ -974,11 +986,30 @@ xfs_mountfs(
                if (error)
                        xfs_warn(mp,
        "Unable to allocate reserve blocks. Continuing without reserve pool.");
+
+               /* Recover any CoW blocks that never got remapped. */
+               error = xfs_reflink_recover_cow(mp);
+               if (error) {
+                       xfs_err(mp,
+       "Error %d recovering leftover CoW allocations.", error);
+                       xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+                       goto out_quota;
+               }
+
+               /* Reserve AG blocks for future btree expansion. */
+               error = xfs_fs_reserve_ag_blocks(mp);
+               if (error && error != -ENOSPC)
+                       goto out_agresv;
        }
 
        return 0;
 
+ out_agresv:
+       xfs_fs_unreserve_ag_blocks(mp);
+ out_quota:
+       xfs_qm_unmount_quotas(mp);
  out_rtunmount:
+       mp->m_super->s_flags &= ~MS_ACTIVE;
        xfs_rtunmount_inodes(mp);
  out_rele_rip:
        IRELE(rip);
@@ -1019,7 +1050,9 @@ xfs_unmountfs(
        int                     error;
 
        cancel_delayed_work_sync(&mp->m_eofblocks_work);
+       cancel_delayed_work_sync(&mp->m_cowblocks_work);
 
+       xfs_fs_unreserve_ag_blocks(mp);
        xfs_qm_unmount_quotas(mp);
        xfs_rtunmount_inodes(mp);
        IRELE(mp->m_rootip);