diff options
author | Steve French <sfrench@us.ibm.com> | 2006-06-25 11:57:32 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-06-25 11:57:32 -0400 |
commit | bbe5d235ee201705530a7153b57e141cd77d818b (patch) | |
tree | e98c31b4cb2ced6357a87a02596f9ecdbd6dbb26 /fs/xfs/xfs_mount.c | |
parent | 189acaaef81b1d71aedd0d28810de24160c2e781 (diff) | |
parent | dfd8317d3340f03bc06eba6b58f0ec0861da4a13 (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.c | 54 |
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 | ||
338 | xfs_agnumber_t | 336 | xfs_agnumber_t |
339 | xfs_initialize_perag( | 337 | xfs_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 | */ |
652 | int | 650 | int |
653 | xfs_mountfs( | 651 | xfs_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( | |||
1094 | int | 1082 | int |
1095 | xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | 1083 | xfs_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; |