aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_mount.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-06-25 11:57:32 -0400
committerSteve French <sfrench@us.ibm.com>2006-06-25 11:57:32 -0400
commitbbe5d235ee201705530a7153b57e141cd77d818b (patch)
treee98c31b4cb2ced6357a87a02596f9ecdbd6dbb26 /fs/xfs/xfs_mount.c
parent189acaaef81b1d71aedd0d28810de24160c2e781 (diff)
parentdfd8317d3340f03bc06eba6b58f0ec0861da4a13 (diff)
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'fs/xfs/xfs_mount.c')
-rw-r--r--fs/xfs/xfs_mount.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index c0b1c2906880..10dbf203c62f 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -24,14 +24,12 @@
24#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h" 25#include "xfs_sb.h"
26#include "xfs_ag.h" 26#include "xfs_ag.h"
27#include "xfs_dir.h"
28#include "xfs_dir2.h" 27#include "xfs_dir2.h"
29#include "xfs_dmapi.h" 28#include "xfs_dmapi.h"
30#include "xfs_mount.h" 29#include "xfs_mount.h"
31#include "xfs_bmap_btree.h" 30#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h" 31#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h" 32#include "xfs_ialloc_btree.h"
34#include "xfs_dir_sf.h"
35#include "xfs_dir2_sf.h" 33#include "xfs_dir2_sf.h"
36#include "xfs_attr_sf.h" 34#include "xfs_attr_sf.h"
37#include "xfs_dinode.h" 35#include "xfs_dinode.h"
@@ -196,7 +194,7 @@ xfs_mount_free(
196 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1); 194 kmem_free(mp->m_logname, strlen(mp->m_logname) + 1);
197 195
198 if (remove_bhv) { 196 if (remove_bhv) {
199 struct vfs *vfsp = XFS_MTOVFS(mp); 197 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
200 198
201 bhv_remove_all_vfsops(vfsp, 0); 199 bhv_remove_all_vfsops(vfsp, 0);
202 VFS_REMOVEBHV(vfsp, &mp->m_bhv); 200 VFS_REMOVEBHV(vfsp, &mp->m_bhv);
@@ -337,7 +335,7 @@ xfs_mount_validate_sb(
337 335
338xfs_agnumber_t 336xfs_agnumber_t
339xfs_initialize_perag( 337xfs_initialize_perag(
340 struct vfs *vfs, 338 bhv_vfs_t *vfs,
341 xfs_mount_t *mp, 339 xfs_mount_t *mp,
342 xfs_agnumber_t agcount) 340 xfs_agnumber_t agcount)
343{ 341{
@@ -651,14 +649,14 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp)
651 */ 649 */
652int 650int
653xfs_mountfs( 651xfs_mountfs(
654 vfs_t *vfsp, 652 bhv_vfs_t *vfsp,
655 xfs_mount_t *mp, 653 xfs_mount_t *mp,
656 int mfsi_flags) 654 int mfsi_flags)
657{ 655{
658 xfs_buf_t *bp; 656 xfs_buf_t *bp;
659 xfs_sb_t *sbp = &(mp->m_sb); 657 xfs_sb_t *sbp = &(mp->m_sb);
660 xfs_inode_t *rip; 658 xfs_inode_t *rip;
661 vnode_t *rvp = NULL; 659 bhv_vnode_t *rvp = NULL;
662 int readio_log, writeio_log; 660 int readio_log, writeio_log;
663 xfs_daddr_t d; 661 xfs_daddr_t d;
664 __uint64_t ret64; 662 __uint64_t ret64;
@@ -934,18 +932,7 @@ xfs_mountfs(
934 vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid; 932 vfsp->vfs_altfsid = (xfs_fsid_t *)mp->m_fixedfsid;
935 mp->m_dmevmask = 0; /* not persistent; set after each mount */ 933 mp->m_dmevmask = 0; /* not persistent; set after each mount */
936 934
937 /* 935 xfs_dir_mount(mp);
938 * Select the right directory manager.
939 */
940 mp->m_dirops =
941 XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
942 xfsv2_dirops :
943 xfsv1_dirops;
944
945 /*
946 * Initialize directory manager's entries.
947 */
948 XFS_DIR_MOUNT(mp);
949 936
950 /* 937 /*
951 * Initialize the attribute manager's entries. 938 * Initialize the attribute manager's entries.
@@ -1006,8 +993,9 @@ xfs_mountfs(
1006 993
1007 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) { 994 if (unlikely((rip->i_d.di_mode & S_IFMT) != S_IFDIR)) {
1008 cmn_err(CE_WARN, "XFS: corrupted root inode"); 995 cmn_err(CE_WARN, "XFS: corrupted root inode");
1009 prdev("Root inode %llu is not a directory", 996 cmn_err(CE_WARN, "Device %s - root %llu is not a directory",
1010 mp->m_ddev_targp, (unsigned long long)rip->i_ino); 997 XFS_BUFTARG_NAME(mp->m_ddev_targp),
998 (unsigned long long)rip->i_ino);
1011 xfs_iunlock(rip, XFS_ILOCK_EXCL); 999 xfs_iunlock(rip, XFS_ILOCK_EXCL);
1012 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW, 1000 XFS_ERROR_REPORT("xfs_mountfs_int(2)", XFS_ERRLEVEL_LOW,
1013 mp); 1001 mp);
@@ -1094,7 +1082,7 @@ xfs_mountfs(
1094int 1082int
1095xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) 1083xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
1096{ 1084{
1097 struct vfs *vfsp = XFS_MTOVFS(mp); 1085 struct bhv_vfs *vfsp = XFS_MTOVFS(mp);
1098#if defined(DEBUG) || defined(INDUCE_IO_ERROR) 1086#if defined(DEBUG) || defined(INDUCE_IO_ERROR)
1099 int64_t fsid; 1087 int64_t fsid;
1100#endif 1088#endif
@@ -1254,6 +1242,26 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
1254 1242
1255 xfs_trans_log_buf(tp, bp, first, last); 1243 xfs_trans_log_buf(tp, bp, first, last);
1256} 1244}
1245
1246/*
1247 * In order to avoid ENOSPC-related deadlock caused by
1248 * out-of-order locking of AGF buffer (PV 947395), we place
1249 * constraints on the relationship among actual allocations for
1250 * data blocks, freelist blocks, and potential file data bmap
1251 * btree blocks. However, these restrictions may result in no
1252 * actual space allocated for a delayed extent, for example, a data
1253 * block in a certain AG is allocated but there is no additional
1254 * block for the additional bmap btree block due to a split of the
1255 * bmap btree of the file. The result of this may lead to an
1256 * infinite loop in xfssyncd when the file gets flushed to disk and
1257 * all delayed extents need to be actually allocated. To get around
1258 * this, we explicitly set aside a few blocks which will not be
1259 * reserved in delayed allocation. Considering the minimum number of
1260 * needed freelist blocks is 4 fsbs, a potential split of file's bmap
1261 * btree requires 1 fsb, so we set the number of set-aside blocks to 8.
1262*/
1263#define SET_ASIDE_BLOCKS 8
1264
1257/* 1265/*
1258 * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply 1266 * xfs_mod_incore_sb_unlocked() is a utility routine common used to apply
1259 * a delta to a specified field in the in-core superblock. Simply 1267 * a delta to a specified field in the in-core superblock. Simply
@@ -1298,7 +1306,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
1298 return 0; 1306 return 0;
1299 case XFS_SBS_FDBLOCKS: 1307 case XFS_SBS_FDBLOCKS:
1300 1308
1301 lcounter = (long long)mp->m_sb.sb_fdblocks; 1309 lcounter = (long long)mp->m_sb.sb_fdblocks - SET_ASIDE_BLOCKS;
1302 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail); 1310 res_used = (long long)(mp->m_resblks - mp->m_resblks_avail);
1303 1311
1304 if (delta > 0) { /* Putting blocks back */ 1312 if (delta > 0) { /* Putting blocks back */
@@ -1332,7 +1340,7 @@ xfs_mod_incore_sb_unlocked(xfs_mount_t *mp, xfs_sb_field_t field,
1332 } 1340 }
1333 } 1341 }
1334 1342
1335 mp->m_sb.sb_fdblocks = lcounter; 1343 mp->m_sb.sb_fdblocks = lcounter + SET_ASIDE_BLOCKS;
1336 return 0; 1344 return 0;
1337 case XFS_SBS_FREXTENTS: 1345 case XFS_SBS_FREXTENTS:
1338 lcounter = (long long)mp->m_sb.sb_frextents; 1346 lcounter = (long long)mp->m_sb.sb_frextents;