aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_inode.c80
-rw-r--r--fs/xfs/xfs_inode.h4
-rw-r--r--fs/xfs/xfs_log_recover.c2
3 files changed, 37 insertions, 49 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 083395cd675b..1d5c28b144ae 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -262,15 +262,11 @@ xfs_inotobp(
262 * If a non-zero error is returned, then the contents of bpp and 262 * If a non-zero error is returned, then the contents of bpp and
263 * dipp are undefined. 263 * dipp are undefined.
264 * 264 *
265 * If the inode is new and has not yet been initialized, use xfs_imap() 265 * The inode is expected to already been mapped to its buffer and read
266 * to determine the size and location of the buffer to read from disk. 266 * in once, thus we can use the mapping information stored in the inode
267 * If the inode has already been mapped to its buffer and read in once, 267 * rather than calling xfs_imap(). This allows us to avoid the overhead
268 * then use the mapping information stored in the inode rather than 268 * of looking at the inode btree for small block file systems
269 * calling xfs_imap(). This allows us to avoid the overhead of looking 269 * (see xfs_dilocate()).
270 * at the inode btree for small block file systems (see xfs_dilocate()).
271 * We can tell whether the inode has been mapped in before by comparing
272 * its disk block address to 0. Only uninitialized inodes will have
273 * 0 for the disk block address.
274 */ 270 */
275int 271int
276xfs_itobp( 272xfs_itobp(
@@ -279,40 +275,19 @@ xfs_itobp(
279 xfs_inode_t *ip, 275 xfs_inode_t *ip,
280 xfs_dinode_t **dipp, 276 xfs_dinode_t **dipp,
281 xfs_buf_t **bpp, 277 xfs_buf_t **bpp,
282 xfs_daddr_t bno,
283 uint imap_flags,
284 uint buf_flags) 278 uint buf_flags)
285{ 279{
286 xfs_imap_t imap; 280 xfs_imap_t imap;
287 xfs_buf_t *bp; 281 xfs_buf_t *bp;
288 int error; 282 int error;
289 283
290 if (ip->i_blkno == (xfs_daddr_t)0) { 284 ASSERT(ip->i_blkno != 0);
291 imap.im_blkno = bno;
292 error = xfs_imap(mp, tp, ip->i_ino, &imap,
293 XFS_IMAP_LOOKUP | imap_flags);
294 if (error)
295 return error;
296 285
297 /* 286 imap.im_blkno = ip->i_blkno;
298 * Fill in the fields in the inode that will be used to 287 imap.im_len = ip->i_len;
299 * map the inode to its buffer from now on. 288 imap.im_boffset = ip->i_boffset;
300 */
301 ip->i_blkno = imap.im_blkno;
302 ip->i_len = imap.im_len;
303 ip->i_boffset = imap.im_boffset;
304 } else {
305 /*
306 * We've already mapped the inode once, so just use the
307 * mapping that we saved the first time.
308 */
309 imap.im_blkno = ip->i_blkno;
310 imap.im_len = ip->i_len;
311 imap.im_boffset = ip->i_boffset;
312 }
313 ASSERT(bno == 0 || bno == imap.im_blkno);
314 289
315 error = xfs_imap_to_bp(mp, tp, &imap, &bp, buf_flags, imap_flags); 290 error = xfs_imap_to_bp(mp, tp, &imap, &bp, buf_flags, 0);
316 if (error) 291 if (error)
317 return error; 292 return error;
318 293
@@ -882,6 +857,7 @@ xfs_iread(
882 xfs_buf_t *bp; 857 xfs_buf_t *bp;
883 xfs_dinode_t *dip; 858 xfs_dinode_t *dip;
884 xfs_inode_t *ip; 859 xfs_inode_t *ip;
860 xfs_imap_t imap;
885 int error; 861 int error;
886 862
887 ip = xfs_inode_alloc(mp, ino); 863 ip = xfs_inode_alloc(mp, ino);
@@ -889,15 +865,27 @@ xfs_iread(
889 return ENOMEM; 865 return ENOMEM;
890 866
891 /* 867 /*
892 * Get pointer's to the on-disk inode and the buffer containing it. 868 * Get pointers to the on-disk inode and the buffer containing it.
893 * If the inode number refers to a block outside the file system
894 * then xfs_itobp() will return NULL. In this case we should
895 * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will
896 * know that this is a new incore inode.
897 */ 869 */
898 error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags, XFS_BUF_LOCK); 870 imap.im_blkno = bno;
871 error = xfs_imap(mp, tp, ip->i_ino, &imap,
872 XFS_IMAP_LOOKUP | imap_flags);
873 if (error)
874 goto out_destroy_inode;
875
876 /*
877 * Fill in the fields in the inode that will be used to
878 * map the inode to its buffer from now on.
879 */
880 ip->i_blkno = imap.im_blkno;
881 ip->i_len = imap.im_len;
882 ip->i_boffset = imap.im_boffset;
883 ASSERT(bno == 0 || bno == imap.im_blkno);
884
885 error = xfs_imap_to_bp(mp, tp, &imap, &bp, XFS_BUF_LOCK, imap_flags);
899 if (error) 886 if (error)
900 goto out_destroy_inode; 887 goto out_destroy_inode;
888 dip = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset);
901 889
902 /* 890 /*
903 * If we got something that isn't an inode it means someone 891 * If we got something that isn't an inode it means someone
@@ -1878,7 +1866,7 @@ xfs_iunlink(
1878 * Here we put the head pointer into our next pointer, 1866 * Here we put the head pointer into our next pointer,
1879 * and then we fall through to point the head at us. 1867 * and then we fall through to point the head at us.
1880 */ 1868 */
1881 error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK); 1869 error = xfs_itobp(mp, tp, ip, &dip, &ibp, XFS_BUF_LOCK);
1882 if (error) 1870 if (error)
1883 return error; 1871 return error;
1884 1872
@@ -1960,7 +1948,7 @@ xfs_iunlink_remove(
1960 * of dealing with the buffer when there is no need to 1948 * of dealing with the buffer when there is no need to
1961 * change it. 1949 * change it.
1962 */ 1950 */
1963 error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK); 1951 error = xfs_itobp(mp, tp, ip, &dip, &ibp, XFS_BUF_LOCK);
1964 if (error) { 1952 if (error) {
1965 cmn_err(CE_WARN, 1953 cmn_err(CE_WARN,
1966 "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.", 1954 "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.",
@@ -2022,7 +2010,7 @@ xfs_iunlink_remove(
2022 * Now last_ibp points to the buffer previous to us on 2010 * Now last_ibp points to the buffer previous to us on
2023 * the unlinked list. Pull us from the list. 2011 * the unlinked list. Pull us from the list.
2024 */ 2012 */
2025 error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK); 2013 error = xfs_itobp(mp, tp, ip, &dip, &ibp, XFS_BUF_LOCK);
2026 if (error) { 2014 if (error) {
2027 cmn_err(CE_WARN, 2015 cmn_err(CE_WARN,
2028 "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.", 2016 "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.",
@@ -2277,7 +2265,7 @@ xfs_ifree(
2277 2265
2278 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 2266 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
2279 2267
2280 error = xfs_itobp(ip->i_mount, tp, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK); 2268 error = xfs_itobp(ip->i_mount, tp, ip, &dip, &ibp, XFS_BUF_LOCK);
2281 if (error) 2269 if (error)
2282 return error; 2270 return error;
2283 2271
@@ -3191,7 +3179,7 @@ xfs_iflush(
3191 /* 3179 /*
3192 * Get the buffer containing the on-disk inode. 3180 * Get the buffer containing the on-disk inode.
3193 */ 3181 */
3194 error = xfs_itobp(mp, NULL, ip, &dip, &bp, 0, 0, 3182 error = xfs_itobp(mp, NULL, ip, &dip, &bp,
3195 noblock ? XFS_BUF_TRYLOCK : XFS_BUF_LOCK); 3183 noblock ? XFS_BUF_TRYLOCK : XFS_BUF_LOCK);
3196 if (error || !bp) { 3184 if (error || !bp) {
3197 xfs_ifunlock(ip); 3185 xfs_ifunlock(ip);
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 705083a8ffaf..ec8b539439d3 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -157,7 +157,7 @@ typedef struct xfs_icdinode {
157#define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */ 157#define XFS_IFEXTIREC 0x08 /* Indirection array of extent blocks */
158 158
159/* 159/*
160 * Flags for xfs_inotobp, xfs_itobp(), xfs_imap() and xfs_dilocate(). 160 * Flags for xfs_inotobp, xfs_imap() and xfs_dilocate().
161 */ 161 */
162#define XFS_IMAP_LOOKUP 0x1 162#define XFS_IMAP_LOOKUP 0x1
163#define XFS_IMAP_BULKSTAT 0x2 163#define XFS_IMAP_BULKSTAT 0x2
@@ -550,7 +550,7 @@ int xfs_inotobp(struct xfs_mount *, struct xfs_trans *,
550 struct xfs_buf **, int *, uint); 550 struct xfs_buf **, int *, uint);
551int xfs_itobp(struct xfs_mount *, struct xfs_trans *, 551int xfs_itobp(struct xfs_mount *, struct xfs_trans *,
552 struct xfs_inode *, struct xfs_dinode **, 552 struct xfs_inode *, struct xfs_dinode **,
553 struct xfs_buf **, xfs_daddr_t, uint, uint); 553 struct xfs_buf **, uint);
554void xfs_dinode_from_disk(struct xfs_icdinode *, 554void xfs_dinode_from_disk(struct xfs_icdinode *,
555 struct xfs_dinode *); 555 struct xfs_dinode *);
556void xfs_dinode_to_disk(struct xfs_dinode *, 556void xfs_dinode_to_disk(struct xfs_dinode *,
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 841398d24211..48bdfa4dc290 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3169,7 +3169,7 @@ xlog_recover_process_one_iunlink(
3169 * Get the on disk inode to find the next inode in the bucket. 3169 * Get the on disk inode to find the next inode in the bucket.
3170 */ 3170 */
3171 ASSERT(ip != NULL); 3171 ASSERT(ip != NULL);
3172 error = xfs_itobp(mp, NULL, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK); 3172 error = xfs_itobp(mp, NULL, ip, &dip, &ibp, XFS_BUF_LOCK);
3173 if (error) 3173 if (error)
3174 goto fail; 3174 goto fail;
3175 3175