diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 85 |
1 files changed, 37 insertions, 48 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 001aa893ed59..3a137e9f9a7d 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -77,48 +77,44 @@ xfs_get_extsz_hint( | |||
77 | } | 77 | } |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * This is a wrapper routine around the xfs_ilock() routine used to centralize | 80 | * These two are wrapper routines around the xfs_ilock() routine used to |
81 | * some grungy code. It is used in places that wish to lock the inode solely | 81 | * centralize some grungy code. They are used in places that wish to lock the |
82 | * for reading the extents. The reason these places can't just call | 82 | * inode solely for reading the extents. The reason these places can't just |
83 | * xfs_ilock(SHARED) is that the inode lock also guards to bringing in of the | 83 | * call xfs_ilock(ip, XFS_ILOCK_SHARED) is that the inode lock also guards to |
84 | * extents from disk for a file in b-tree format. If the inode is in b-tree | 84 | * bringing in of the extents from disk for a file in b-tree format. If the |
85 | * format, then we need to lock the inode exclusively until the extents are read | 85 | * inode is in b-tree format, then we need to lock the inode exclusively until |
86 | * in. Locking it exclusively all the time would limit our parallelism | 86 | * the extents are read in. Locking it exclusively all the time would limit |
87 | * unnecessarily, though. What we do instead is check to see if the extents | 87 | * our parallelism unnecessarily, though. What we do instead is check to see |
88 | * have been read in yet, and only lock the inode exclusively if they have not. | 88 | * if the extents have been read in yet, and only lock the inode exclusively |
89 | * if they have not. | ||
89 | * | 90 | * |
90 | * The function returns a value which should be given to the corresponding | 91 | * The functions return a value which should be given to the corresponding |
91 | * xfs_iunlock_map_shared(). This value is the mode in which the lock was | 92 | * xfs_iunlock() call. |
92 | * actually taken. | ||
93 | */ | 93 | */ |
94 | uint | 94 | uint |
95 | xfs_ilock_map_shared( | 95 | xfs_ilock_data_map_shared( |
96 | xfs_inode_t *ip) | 96 | struct xfs_inode *ip) |
97 | { | 97 | { |
98 | uint lock_mode; | 98 | uint lock_mode = XFS_ILOCK_SHARED; |
99 | 99 | ||
100 | if ((ip->i_d.di_format == XFS_DINODE_FMT_BTREE) && | 100 | if (ip->i_d.di_format == XFS_DINODE_FMT_BTREE && |
101 | ((ip->i_df.if_flags & XFS_IFEXTENTS) == 0)) { | 101 | (ip->i_df.if_flags & XFS_IFEXTENTS) == 0) |
102 | lock_mode = XFS_ILOCK_EXCL; | 102 | lock_mode = XFS_ILOCK_EXCL; |
103 | } else { | ||
104 | lock_mode = XFS_ILOCK_SHARED; | ||
105 | } | ||
106 | |||
107 | xfs_ilock(ip, lock_mode); | 103 | xfs_ilock(ip, lock_mode); |
108 | |||
109 | return lock_mode; | 104 | return lock_mode; |
110 | } | 105 | } |
111 | 106 | ||
112 | /* | 107 | uint |
113 | * This is simply the unlock routine to go with xfs_ilock_map_shared(). | 108 | xfs_ilock_attr_map_shared( |
114 | * All it does is call xfs_iunlock() with the given lock_mode. | 109 | struct xfs_inode *ip) |
115 | */ | ||
116 | void | ||
117 | xfs_iunlock_map_shared( | ||
118 | xfs_inode_t *ip, | ||
119 | unsigned int lock_mode) | ||
120 | { | 110 | { |
121 | xfs_iunlock(ip, lock_mode); | 111 | uint lock_mode = XFS_ILOCK_SHARED; |
112 | |||
113 | if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE && | ||
114 | (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0) | ||
115 | lock_mode = XFS_ILOCK_EXCL; | ||
116 | xfs_ilock(ip, lock_mode); | ||
117 | return lock_mode; | ||
122 | } | 118 | } |
123 | 119 | ||
124 | /* | 120 | /* |
@@ -588,9 +584,9 @@ xfs_lookup( | |||
588 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | 584 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
589 | return XFS_ERROR(EIO); | 585 | return XFS_ERROR(EIO); |
590 | 586 | ||
591 | lock_mode = xfs_ilock_map_shared(dp); | 587 | lock_mode = xfs_ilock_data_map_shared(dp); |
592 | error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name); | 588 | error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name); |
593 | xfs_iunlock_map_shared(dp, lock_mode); | 589 | xfs_iunlock(dp, lock_mode); |
594 | 590 | ||
595 | if (error) | 591 | if (error) |
596 | goto out; | 592 | goto out; |
@@ -2141,8 +2137,8 @@ xfs_ifree_cluster( | |||
2141 | { | 2137 | { |
2142 | xfs_mount_t *mp = free_ip->i_mount; | 2138 | xfs_mount_t *mp = free_ip->i_mount; |
2143 | int blks_per_cluster; | 2139 | int blks_per_cluster; |
2140 | int inodes_per_cluster; | ||
2144 | int nbufs; | 2141 | int nbufs; |
2145 | int ninodes; | ||
2146 | int i, j; | 2142 | int i, j; |
2147 | xfs_daddr_t blkno; | 2143 | xfs_daddr_t blkno; |
2148 | xfs_buf_t *bp; | 2144 | xfs_buf_t *bp; |
@@ -2152,18 +2148,11 @@ xfs_ifree_cluster( | |||
2152 | struct xfs_perag *pag; | 2148 | struct xfs_perag *pag; |
2153 | 2149 | ||
2154 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum)); | 2150 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum)); |
2155 | if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { | 2151 | blks_per_cluster = xfs_icluster_size_fsb(mp); |
2156 | blks_per_cluster = 1; | 2152 | inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog; |
2157 | ninodes = mp->m_sb.sb_inopblock; | 2153 | nbufs = mp->m_ialloc_blks / blks_per_cluster; |
2158 | nbufs = XFS_IALLOC_BLOCKS(mp); | ||
2159 | } else { | ||
2160 | blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) / | ||
2161 | mp->m_sb.sb_blocksize; | ||
2162 | ninodes = blks_per_cluster * mp->m_sb.sb_inopblock; | ||
2163 | nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster; | ||
2164 | } | ||
2165 | 2154 | ||
2166 | for (j = 0; j < nbufs; j++, inum += ninodes) { | 2155 | for (j = 0; j < nbufs; j++, inum += inodes_per_cluster) { |
2167 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), | 2156 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), |
2168 | XFS_INO_TO_AGBNO(mp, inum)); | 2157 | XFS_INO_TO_AGBNO(mp, inum)); |
2169 | 2158 | ||
@@ -2225,7 +2214,7 @@ xfs_ifree_cluster( | |||
2225 | * transaction stale above, which means there is no point in | 2214 | * transaction stale above, which means there is no point in |
2226 | * even trying to lock them. | 2215 | * even trying to lock them. |
2227 | */ | 2216 | */ |
2228 | for (i = 0; i < ninodes; i++) { | 2217 | for (i = 0; i < inodes_per_cluster; i++) { |
2229 | retry: | 2218 | retry: |
2230 | rcu_read_lock(); | 2219 | rcu_read_lock(); |
2231 | ip = radix_tree_lookup(&pag->pag_ici_root, | 2220 | ip = radix_tree_lookup(&pag->pag_ici_root, |
@@ -2906,13 +2895,13 @@ xfs_iflush_cluster( | |||
2906 | 2895 | ||
2907 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); | 2896 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); |
2908 | 2897 | ||
2909 | inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; | 2898 | inodes_per_cluster = mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog; |
2910 | ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); | 2899 | ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); |
2911 | ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS); | 2900 | ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS); |
2912 | if (!ilist) | 2901 | if (!ilist) |
2913 | goto out_put; | 2902 | goto out_put; |
2914 | 2903 | ||
2915 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); | 2904 | mask = ~(((mp->m_inode_cluster_size >> mp->m_sb.sb_inodelog)) - 1); |
2916 | first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask; | 2905 | first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask; |
2917 | rcu_read_lock(); | 2906 | rcu_read_lock(); |
2918 | /* really need a gang lookup range call here */ | 2907 | /* really need a gang lookup range call here */ |