diff options
71 files changed, 285 insertions, 4595 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index c5ea26d73bea..3e807b828e22 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include "xfs_inum.h" | 21 | #include "xfs_inum.h" |
| 22 | #include "xfs_sb.h" | 22 | #include "xfs_sb.h" |
| 23 | #include "xfs_ag.h" | 23 | #include "xfs_ag.h" |
| 24 | #include "xfs_dir.h" | ||
| 25 | #include "xfs_dir2.h" | 24 | #include "xfs_dir2.h" |
| 26 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| @@ -29,7 +28,6 @@ | |||
| 29 | #include "xfs_bmap_btree.h" | 28 | #include "xfs_bmap_btree.h" |
| 30 | #include "xfs_alloc_btree.h" | 29 | #include "xfs_alloc_btree.h" |
| 31 | #include "xfs_ialloc_btree.h" | 30 | #include "xfs_ialloc_btree.h" |
| 32 | #include "xfs_dir_sf.h" | ||
| 33 | #include "xfs_dir2_sf.h" | 31 | #include "xfs_dir2_sf.h" |
| 34 | #include "xfs_attr_sf.h" | 32 | #include "xfs_attr_sf.h" |
| 35 | #include "xfs_dinode.h" | 33 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index d32a9edc43a9..5fb75d9151f2 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include "xfs_log.h" | 21 | #include "xfs_log.h" |
| 22 | #include "xfs_trans.h" | 22 | #include "xfs_trans.h" |
| 23 | #include "xfs_sb.h" | 23 | #include "xfs_sb.h" |
| 24 | #include "xfs_dir.h" | ||
| 25 | #include "xfs_mount.h" | 24 | #include "xfs_mount.h" |
| 26 | #include "xfs_export.h" | 25 | #include "xfs_export.h" |
| 27 | 26 | ||
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index cf65a8364d5a..70662371bb11 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include "xfs_inum.h" | 21 | #include "xfs_inum.h" |
| 22 | #include "xfs_sb.h" | 22 | #include "xfs_sb.h" |
| 23 | #include "xfs_ag.h" | 23 | #include "xfs_ag.h" |
| 24 | #include "xfs_dir.h" | ||
| 25 | #include "xfs_dir2.h" | 24 | #include "xfs_dir2.h" |
| 26 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_alloc.h" | 31 | #include "xfs_alloc.h" |
| 33 | #include "xfs_btree.h" | 32 | #include "xfs_btree.h" |
| 34 | #include "xfs_attr_sf.h" | 33 | #include "xfs_attr_sf.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
| 38 | #include "xfs_inode.h" | 36 | #include "xfs_inode.h" |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index a0e247c71323..6e52a5dd38d8 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
| @@ -31,7 +30,6 @@ | |||
| 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_attr_sf.h" | 33 | #include "xfs_attr_sf.h" |
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_dinode.h" | 35 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 484daef91d7f..12810baeb5d4 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 8e5468704816..5d9cfd91ad08 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 7fae922d54de..f2a0778536f4 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/linux-2.6/xfs_vfs.c b/fs/xfs/linux-2.6/xfs_vfs.c index 4fc884bcb4fd..6145e8bd0be2 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.c +++ b/fs/xfs/linux-2.6/xfs_vfs.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_imap.h" | 27 | #include "xfs_imap.h" |
| 29 | #include "xfs_alloc.h" | 28 | #include "xfs_alloc.h" |
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 46bec66bb4d8..3aa771531856 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index 21ad5a55e014..5b2dcc58b244 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 00fb54d48999..e23e45535c48 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
| @@ -24,7 +24,6 @@ | |||
| 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_alloc.h" | 28 | #include "xfs_alloc.h" |
| 30 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
| @@ -33,7 +32,6 @@ | |||
| 33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
| 34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
| 35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
| 36 | #include "xfs_dir_sf.h" | ||
| 37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
| 38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
| 39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index d93d3a1064ed..e95e99f7168f 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
| @@ -24,7 +24,6 @@ | |||
| 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_alloc.h" | 28 | #include "xfs_alloc.h" |
| 30 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
| @@ -33,7 +32,6 @@ | |||
| 33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
| 34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
| 35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
| 36 | #include "xfs_dir_sf.h" | ||
| 37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
| 38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
| 39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c index 0570f7733550..6f858fb81a36 100644 --- a/fs/xfs/quota/xfs_qm_stats.c +++ b/fs/xfs/quota/xfs_qm_stats.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index c93072be6792..ed620c4d1594 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include "xfs_trans.h" | 26 | #include "xfs_trans.h" |
| 27 | #include "xfs_sb.h" | 27 | #include "xfs_sb.h" |
| 28 | #include "xfs_ag.h" | 28 | #include "xfs_ag.h" |
| 29 | #include "xfs_dir.h" | ||
| 30 | #include "xfs_dir2.h" | 29 | #include "xfs_dir2.h" |
| 31 | #include "xfs_alloc.h" | 30 | #include "xfs_alloc.h" |
| 32 | #include "xfs_dmapi.h" | 31 | #include "xfs_dmapi.h" |
| @@ -35,7 +34,6 @@ | |||
| 35 | #include "xfs_bmap_btree.h" | 34 | #include "xfs_bmap_btree.h" |
| 36 | #include "xfs_alloc_btree.h" | 35 | #include "xfs_alloc_btree.h" |
| 37 | #include "xfs_ialloc_btree.h" | 36 | #include "xfs_ialloc_btree.h" |
| 38 | #include "xfs_dir_sf.h" | ||
| 39 | #include "xfs_dir2_sf.h" | 37 | #include "xfs_dir2_sf.h" |
| 40 | #include "xfs_attr_sf.h" | 38 | #include "xfs_attr_sf.h" |
| 41 | #include "xfs_dinode.h" | 39 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 9168918db252..0242e9666e8e 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
| @@ -33,7 +32,6 @@ | |||
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_attr_sf.h" | 34 | #include "xfs_attr_sf.h" |
| 36 | #include "xfs_dir_sf.h" | ||
| 37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
| 39 | #include "xfs_inode.h" | 37 | #include "xfs_inode.h" |
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index e1074955386f..4b0cb474be4c 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
| @@ -21,12 +21,10 @@ | |||
| 21 | #include "xfs_bit.h" | 21 | #include "xfs_bit.h" |
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_ag.h" | 23 | #include "xfs_ag.h" |
| 24 | #include "xfs_dir.h" | ||
| 25 | #include "xfs_dir2.h" | 24 | #include "xfs_dir2.h" |
| 26 | #include "xfs_bmap_btree.h" | 25 | #include "xfs_bmap_btree.h" |
| 27 | #include "xfs_alloc_btree.h" | 26 | #include "xfs_alloc_btree.h" |
| 28 | #include "xfs_ialloc_btree.h" | 27 | #include "xfs_ialloc_btree.h" |
| 29 | #include "xfs_dir_sf.h" | ||
| 30 | #include "xfs_dir2_sf.h" | 28 | #include "xfs_dir2_sf.h" |
| 31 | #include "xfs_attr_sf.h" | 29 | #include "xfs_attr_sf.h" |
| 32 | #include "xfs_dinode.h" | 30 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 22af489d3f34..eef6763f3a67 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.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" |
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index a1d92da86ccd..7446556e8021 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.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" |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 4dcef8d1c32f..1a2101043275 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include "xfs_trans.h" | 27 | #include "xfs_trans.h" |
| 28 | #include "xfs_sb.h" | 28 | #include "xfs_sb.h" |
| 29 | #include "xfs_ag.h" | 29 | #include "xfs_ag.h" |
| 30 | #include "xfs_dir.h" | ||
| 31 | #include "xfs_dir2.h" | 30 | #include "xfs_dir2.h" |
| 32 | #include "xfs_dmapi.h" | 31 | #include "xfs_dmapi.h" |
| 33 | #include "xfs_mount.h" | 32 | #include "xfs_mount.h" |
| @@ -35,7 +34,6 @@ | |||
| 35 | #include "xfs_bmap_btree.h" | 34 | #include "xfs_bmap_btree.h" |
| 36 | #include "xfs_alloc_btree.h" | 35 | #include "xfs_alloc_btree.h" |
| 37 | #include "xfs_ialloc_btree.h" | 36 | #include "xfs_ialloc_btree.h" |
| 38 | #include "xfs_dir_sf.h" | ||
| 39 | #include "xfs_dir2_sf.h" | 37 | #include "xfs_dir2_sf.h" |
| 40 | #include "xfs_attr_sf.h" | 38 | #include "xfs_attr_sf.h" |
| 41 | #include "xfs_dinode.h" | 39 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index 5c44343d4a36..9455051f0120 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
| @@ -24,7 +24,6 @@ | |||
| 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" |
| @@ -34,7 +33,6 @@ | |||
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_alloc.h" | 34 | #include "xfs_alloc.h" |
| 36 | #include "xfs_btree.h" | 35 | #include "xfs_btree.h" |
| 37 | #include "xfs_dir_sf.h" | ||
| 38 | #include "xfs_dir2_sf.h" | 36 | #include "xfs_dir2_sf.h" |
| 39 | #include "xfs_attr_sf.h" | 37 | #include "xfs_attr_sf.h" |
| 40 | #include "xfs_dinode.h" | 38 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 4d0ca14039af..3a6137539064 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
| @@ -24,13 +24,11 @@ | |||
| 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_da_btree.h" | 28 | #include "xfs_da_btree.h" |
| 30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_alloc_btree.h" | 30 | #include "xfs_alloc_btree.h" |
| 32 | #include "xfs_ialloc_btree.h" | 31 | #include "xfs_ialloc_btree.h" |
| 33 | #include "xfs_dir_sf.h" | ||
| 34 | #include "xfs_dir2_sf.h" | 32 | #include "xfs_dir2_sf.h" |
| 35 | #include "xfs_attr_sf.h" | 33 | #include "xfs_attr_sf.h" |
| 36 | #include "xfs_dinode.h" | 34 | #include "xfs_dinode.h" |
| @@ -40,13 +38,15 @@ | |||
| 40 | #include "xfs_mount.h" | 38 | #include "xfs_mount.h" |
| 41 | #include "xfs_ialloc.h" | 39 | #include "xfs_ialloc.h" |
| 42 | #include "xfs_itable.h" | 40 | #include "xfs_itable.h" |
| 41 | #include "xfs_dir2_data.h" | ||
| 42 | #include "xfs_dir2_leaf.h" | ||
| 43 | #include "xfs_dir2_block.h" | ||
| 43 | #include "xfs_inode_item.h" | 44 | #include "xfs_inode_item.h" |
| 44 | #include "xfs_extfree_item.h" | 45 | #include "xfs_extfree_item.h" |
| 45 | #include "xfs_alloc.h" | 46 | #include "xfs_alloc.h" |
| 46 | #include "xfs_bmap.h" | 47 | #include "xfs_bmap.h" |
| 47 | #include "xfs_rtalloc.h" | 48 | #include "xfs_rtalloc.h" |
| 48 | #include "xfs_error.h" | 49 | #include "xfs_error.h" |
| 49 | #include "xfs_dir_leaf.h" | ||
| 50 | #include "xfs_attr_leaf.h" | 50 | #include "xfs_attr_leaf.h" |
| 51 | #include "xfs_rw.h" | 51 | #include "xfs_rw.h" |
| 52 | #include "xfs_quota.h" | 52 | #include "xfs_quota.h" |
| @@ -516,7 +516,7 @@ xfs_bmap_add_attrfork_local( | |||
| 516 | dargs.total = mp->m_dirblkfsbs; | 516 | dargs.total = mp->m_dirblkfsbs; |
| 517 | dargs.whichfork = XFS_DATA_FORK; | 517 | dargs.whichfork = XFS_DATA_FORK; |
| 518 | dargs.trans = tp; | 518 | dargs.trans = tp; |
| 519 | error = XFS_DIR_SHORTFORM_TO_SINGLE(mp, &dargs); | 519 | error = xfs_dir2_sf_to_block(&dargs); |
| 520 | } else | 520 | } else |
| 521 | error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, | 521 | error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags, |
| 522 | XFS_DATA_FORK); | 522 | XFS_DATA_FORK); |
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 3b6dfc9b53af..18fb7385d719 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.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" |
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 52d5d095fc35..ee2255bd6562 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.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" |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 290912cbff63..a4aa53974f76 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_inum.h" | 23 | #include "xfs_inum.h" |
| 24 | #include "xfs_trans.h" | 24 | #include "xfs_trans.h" |
| 25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| 28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 29 | #include "xfs_buf_item.h" | 28 | #include "xfs_buf_item.h" |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 260c3d770c02..32ab61d17ace 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
| @@ -24,7 +24,6 @@ | |||
| 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" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
| @@ -43,7 +41,6 @@ | |||
| 43 | #include "xfs_bmap.h" | 41 | #include "xfs_bmap.h" |
| 44 | #include "xfs_attr.h" | 42 | #include "xfs_attr.h" |
| 45 | #include "xfs_attr_leaf.h" | 43 | #include "xfs_attr_leaf.h" |
| 46 | #include "xfs_dir_leaf.h" | ||
| 47 | #include "xfs_dir2_data.h" | 44 | #include "xfs_dir2_data.h" |
| 48 | #include "xfs_dir2_leaf.h" | 45 | #include "xfs_dir2_leaf.h" |
| 49 | #include "xfs_dir2_block.h" | 46 | #include "xfs_dir2_block.h" |
| @@ -159,7 +156,7 @@ xfs_da_split(xfs_da_state_t *state) | |||
| 159 | max = state->path.active - 1; | 156 | max = state->path.active - 1; |
| 160 | ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); | 157 | ASSERT((max >= 0) && (max < XFS_DA_NODE_MAXDEPTH)); |
| 161 | ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || | 158 | ASSERT(state->path.blk[max].magic == XFS_ATTR_LEAF_MAGIC || |
| 162 | state->path.blk[max].magic == XFS_DIRX_LEAF_MAGIC(state->mp)); | 159 | state->path.blk[max].magic == XFS_DIR2_LEAFN_MAGIC); |
| 163 | 160 | ||
| 164 | addblk = &state->path.blk[max]; /* initial dummy value */ | 161 | addblk = &state->path.blk[max]; /* initial dummy value */ |
| 165 | for (i = max; (i >= 0) && addblk; state->path.active--, i--) { | 162 | for (i = max; (i >= 0) && addblk; state->path.active--, i--) { |
| @@ -199,38 +196,7 @@ xfs_da_split(xfs_da_state_t *state) | |||
| 199 | return(error); /* GROT: attr inconsistent */ | 196 | return(error); /* GROT: attr inconsistent */ |
| 200 | addblk = newblk; | 197 | addblk = newblk; |
| 201 | break; | 198 | break; |
| 202 | case XFS_DIR_LEAF_MAGIC: | ||
| 203 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
| 204 | error = xfs_dir_leaf_split(state, oldblk, newblk); | ||
| 205 | if ((error != 0) && (error != ENOSPC)) { | ||
| 206 | return(error); /* GROT: dir is inconsistent */ | ||
| 207 | } | ||
| 208 | if (!error) { | ||
| 209 | addblk = newblk; | ||
| 210 | break; | ||
| 211 | } | ||
| 212 | /* | ||
| 213 | * Entry wouldn't fit, split the leaf again. | ||
| 214 | */ | ||
| 215 | state->extravalid = 1; | ||
| 216 | if (state->inleaf) { | ||
| 217 | state->extraafter = 0; /* before newblk */ | ||
| 218 | error = xfs_dir_leaf_split(state, oldblk, | ||
| 219 | &state->extrablk); | ||
| 220 | if (error) | ||
| 221 | return(error); /* GROT: dir incon. */ | ||
| 222 | addblk = newblk; | ||
| 223 | } else { | ||
| 224 | state->extraafter = 1; /* after newblk */ | ||
| 225 | error = xfs_dir_leaf_split(state, newblk, | ||
| 226 | &state->extrablk); | ||
| 227 | if (error) | ||
| 228 | return(error); /* GROT: dir incon. */ | ||
| 229 | addblk = newblk; | ||
| 230 | } | ||
| 231 | break; | ||
| 232 | case XFS_DIR2_LEAFN_MAGIC: | 199 | case XFS_DIR2_LEAFN_MAGIC: |
| 233 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
| 234 | error = xfs_dir2_leafn_split(state, oldblk, newblk); | 200 | error = xfs_dir2_leafn_split(state, oldblk, newblk); |
| 235 | if (error) | 201 | if (error) |
| 236 | return error; | 202 | return error; |
| @@ -363,7 +329,6 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
| 363 | size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - | 329 | size = (int)((char *)&oldroot->btree[be16_to_cpu(oldroot->hdr.count)] - |
| 364 | (char *)oldroot); | 330 | (char *)oldroot); |
| 365 | } else { | 331 | } else { |
| 366 | ASSERT(XFS_DIR_IS_V2(mp)); | ||
| 367 | ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); | 332 | ASSERT(be16_to_cpu(oldroot->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); |
| 368 | leaf = (xfs_dir2_leaf_t *)oldroot; | 333 | leaf = (xfs_dir2_leaf_t *)oldroot; |
| 369 | size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - | 334 | size = (int)((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] - |
| @@ -379,8 +344,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | |||
| 379 | * Set up the new root node. | 344 | * Set up the new root node. |
| 380 | */ | 345 | */ |
| 381 | error = xfs_da_node_create(args, | 346 | error = xfs_da_node_create(args, |
| 382 | args->whichfork == XFS_DATA_FORK && | 347 | (args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0, |
| 383 | XFS_DIR_IS_V2(mp) ? mp->m_dirleafblk : 0, | ||
| 384 | be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); | 348 | be16_to_cpu(node->hdr.level) + 1, &bp, args->whichfork); |
| 385 | if (error) | 349 | if (error) |
| 386 | return(error); | 350 | return(error); |
| @@ -427,10 +391,9 @@ xfs_da_node_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
| 427 | ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); | 391 | ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); |
| 428 | 392 | ||
| 429 | /* | 393 | /* |
| 430 | * With V2 the extra block is data or freespace. | 394 | * With V2 dirs the extra block is data or freespace. |
| 431 | */ | 395 | */ |
| 432 | useextra = state->extravalid && (XFS_DIR_IS_V1(state->mp) || | 396 | useextra = state->extravalid && state->args->whichfork == XFS_ATTR_FORK; |
| 433 | state->args->whichfork == XFS_ATTR_FORK); | ||
| 434 | newcount = 1 + useextra; | 397 | newcount = 1 + useextra; |
| 435 | /* | 398 | /* |
| 436 | * Do we have to split the node? | 399 | * Do we have to split the node? |
| @@ -624,7 +587,7 @@ xfs_da_node_add(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | |||
| 624 | ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); | 587 | ASSERT(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC); |
| 625 | ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); | 588 | ASSERT((oldblk->index >= 0) && (oldblk->index <= be16_to_cpu(node->hdr.count))); |
| 626 | ASSERT(newblk->blkno != 0); | 589 | ASSERT(newblk->blkno != 0); |
| 627 | if (state->args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) | 590 | if (state->args->whichfork == XFS_DATA_FORK) |
| 628 | ASSERT(newblk->blkno >= mp->m_dirleafblk && | 591 | ASSERT(newblk->blkno >= mp->m_dirleafblk && |
| 629 | newblk->blkno < mp->m_dirfreeblk); | 592 | newblk->blkno < mp->m_dirfreeblk); |
| 630 | 593 | ||
| @@ -670,7 +633,7 @@ xfs_da_join(xfs_da_state_t *state) | |||
| 670 | save_blk = &state->altpath.blk[ state->path.active-1 ]; | 633 | save_blk = &state->altpath.blk[ state->path.active-1 ]; |
| 671 | ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); | 634 | ASSERT(state->path.blk[0].magic == XFS_DA_NODE_MAGIC); |
| 672 | ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || | 635 | ASSERT(drop_blk->magic == XFS_ATTR_LEAF_MAGIC || |
| 673 | drop_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp)); | 636 | drop_blk->magic == XFS_DIR2_LEAFN_MAGIC); |
| 674 | 637 | ||
| 675 | /* | 638 | /* |
| 676 | * Walk back up the tree joining/deallocating as necessary. | 639 | * Walk back up the tree joining/deallocating as necessary. |
| @@ -693,17 +656,7 @@ xfs_da_join(xfs_da_state_t *state) | |||
| 693 | return(0); | 656 | return(0); |
| 694 | xfs_attr_leaf_unbalance(state, drop_blk, save_blk); | 657 | xfs_attr_leaf_unbalance(state, drop_blk, save_blk); |
| 695 | break; | 658 | break; |
| 696 | case XFS_DIR_LEAF_MAGIC: | ||
| 697 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
| 698 | error = xfs_dir_leaf_toosmall(state, &action); | ||
| 699 | if (error) | ||
| 700 | return(error); | ||
| 701 | if (action == 0) | ||
| 702 | return(0); | ||
| 703 | xfs_dir_leaf_unbalance(state, drop_blk, save_blk); | ||
| 704 | break; | ||
| 705 | case XFS_DIR2_LEAFN_MAGIC: | 659 | case XFS_DIR2_LEAFN_MAGIC: |
| 706 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
| 707 | error = xfs_dir2_leafn_toosmall(state, &action); | 660 | error = xfs_dir2_leafn_toosmall(state, &action); |
| 708 | if (error) | 661 | if (error) |
| 709 | return error; | 662 | return error; |
| @@ -790,7 +743,7 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) | |||
| 790 | ASSERT(bp != NULL); | 743 | ASSERT(bp != NULL); |
| 791 | blkinfo = bp->data; | 744 | blkinfo = bp->data; |
| 792 | if (be16_to_cpu(oldroot->hdr.level) == 1) { | 745 | if (be16_to_cpu(oldroot->hdr.level) == 1) { |
| 793 | ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || | 746 | ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DIR2_LEAFN_MAGIC || |
| 794 | be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); | 747 | be16_to_cpu(blkinfo->magic) == XFS_ATTR_LEAF_MAGIC); |
| 795 | } else { | 748 | } else { |
| 796 | ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); | 749 | ASSERT(be16_to_cpu(blkinfo->magic) == XFS_DA_NODE_MAGIC); |
| @@ -951,14 +904,7 @@ xfs_da_fixhashpath(xfs_da_state_t *state, xfs_da_state_path_t *path) | |||
| 951 | if (count == 0) | 904 | if (count == 0) |
| 952 | return; | 905 | return; |
| 953 | break; | 906 | break; |
| 954 | case XFS_DIR_LEAF_MAGIC: | ||
| 955 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
| 956 | lasthash = xfs_dir_leaf_lasthash(blk->bp, &count); | ||
| 957 | if (count == 0) | ||
| 958 | return; | ||
| 959 | break; | ||
| 960 | case XFS_DIR2_LEAFN_MAGIC: | 907 | case XFS_DIR2_LEAFN_MAGIC: |
| 961 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
| 962 | lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); | 908 | lasthash = xfs_dir2_leafn_lasthash(blk->bp, &count); |
| 963 | if (count == 0) | 909 | if (count == 0) |
| 964 | return; | 910 | return; |
| @@ -1117,10 +1063,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
| 1117 | * Descend thru the B-tree searching each level for the right | 1063 | * Descend thru the B-tree searching each level for the right |
| 1118 | * node to use, until the right hashval is found. | 1064 | * node to use, until the right hashval is found. |
| 1119 | */ | 1065 | */ |
| 1120 | if (args->whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(state->mp)) | 1066 | blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0; |
| 1121 | blkno = state->mp->m_dirleafblk; | ||
| 1122 | else | ||
| 1123 | blkno = 0; | ||
| 1124 | for (blk = &state->path.blk[0], state->path.active = 1; | 1067 | for (blk = &state->path.blk[0], state->path.active = 1; |
| 1125 | state->path.active <= XFS_DA_NODE_MAXDEPTH; | 1068 | state->path.active <= XFS_DA_NODE_MAXDEPTH; |
| 1126 | blk++, state->path.active++) { | 1069 | blk++, state->path.active++) { |
| @@ -1137,7 +1080,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
| 1137 | } | 1080 | } |
| 1138 | curr = blk->bp->data; | 1081 | curr = blk->bp->data; |
| 1139 | ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || | 1082 | ASSERT(be16_to_cpu(curr->magic) == XFS_DA_NODE_MAGIC || |
| 1140 | be16_to_cpu(curr->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || | 1083 | be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC || |
| 1141 | be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); | 1084 | be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC); |
| 1142 | 1085 | ||
| 1143 | /* | 1086 | /* |
| @@ -1190,16 +1133,10 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
| 1190 | blk->index = probe; | 1133 | blk->index = probe; |
| 1191 | blkno = be32_to_cpu(btree->before); | 1134 | blkno = be32_to_cpu(btree->before); |
| 1192 | } | 1135 | } |
| 1193 | } | 1136 | } else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) { |
| 1194 | else if (be16_to_cpu(curr->magic) == XFS_ATTR_LEAF_MAGIC) { | ||
| 1195 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); | 1137 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, NULL); |
| 1196 | break; | 1138 | break; |
| 1197 | } | 1139 | } else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) { |
| 1198 | else if (be16_to_cpu(curr->magic) == XFS_DIR_LEAF_MAGIC) { | ||
| 1199 | blk->hashval = xfs_dir_leaf_lasthash(blk->bp, NULL); | ||
| 1200 | break; | ||
| 1201 | } | ||
| 1202 | else if (be16_to_cpu(curr->magic) == XFS_DIR2_LEAFN_MAGIC) { | ||
| 1203 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); | 1140 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, NULL); |
| 1204 | break; | 1141 | break; |
| 1205 | } | 1142 | } |
| @@ -1212,12 +1149,7 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
| 1212 | * next leaf and keep searching. | 1149 | * next leaf and keep searching. |
| 1213 | */ | 1150 | */ |
| 1214 | for (;;) { | 1151 | for (;;) { |
| 1215 | if (blk->magic == XFS_DIR_LEAF_MAGIC) { | 1152 | if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { |
| 1216 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
| 1217 | retval = xfs_dir_leaf_lookup_int(blk->bp, args, | ||
| 1218 | &blk->index); | ||
| 1219 | } else if (blk->magic == XFS_DIR2_LEAFN_MAGIC) { | ||
| 1220 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
| 1221 | retval = xfs_dir2_leafn_lookup_int(blk->bp, args, | 1153 | retval = xfs_dir2_leafn_lookup_int(blk->bp, args, |
| 1222 | &blk->index, state); | 1154 | &blk->index, state); |
| 1223 | } | 1155 | } |
| @@ -1270,7 +1202,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
| 1270 | old_info = old_blk->bp->data; | 1202 | old_info = old_blk->bp->data; |
| 1271 | new_info = new_blk->bp->data; | 1203 | new_info = new_blk->bp->data; |
| 1272 | ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || | 1204 | ASSERT(old_blk->magic == XFS_DA_NODE_MAGIC || |
| 1273 | old_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || | 1205 | old_blk->magic == XFS_DIR2_LEAFN_MAGIC || |
| 1274 | old_blk->magic == XFS_ATTR_LEAF_MAGIC); | 1206 | old_blk->magic == XFS_ATTR_LEAF_MAGIC); |
| 1275 | ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); | 1207 | ASSERT(old_blk->magic == be16_to_cpu(old_info->magic)); |
| 1276 | ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); | 1208 | ASSERT(new_blk->magic == be16_to_cpu(new_info->magic)); |
| @@ -1280,12 +1212,7 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
| 1280 | case XFS_ATTR_LEAF_MAGIC: | 1212 | case XFS_ATTR_LEAF_MAGIC: |
| 1281 | before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); | 1213 | before = xfs_attr_leaf_order(old_blk->bp, new_blk->bp); |
| 1282 | break; | 1214 | break; |
| 1283 | case XFS_DIR_LEAF_MAGIC: | ||
| 1284 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
| 1285 | before = xfs_dir_leaf_order(old_blk->bp, new_blk->bp); | ||
| 1286 | break; | ||
| 1287 | case XFS_DIR2_LEAFN_MAGIC: | 1215 | case XFS_DIR2_LEAFN_MAGIC: |
| 1288 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
| 1289 | before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); | 1216 | before = xfs_dir2_leafn_order(old_blk->bp, new_blk->bp); |
| 1290 | break; | 1217 | break; |
| 1291 | case XFS_DA_NODE_MAGIC: | 1218 | case XFS_DA_NODE_MAGIC: |
| @@ -1404,7 +1331,7 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
| 1404 | save_info = save_blk->bp->data; | 1331 | save_info = save_blk->bp->data; |
| 1405 | drop_info = drop_blk->bp->data; | 1332 | drop_info = drop_blk->bp->data; |
| 1406 | ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || | 1333 | ASSERT(save_blk->magic == XFS_DA_NODE_MAGIC || |
| 1407 | save_blk->magic == XFS_DIRX_LEAF_MAGIC(state->mp) || | 1334 | save_blk->magic == XFS_DIR2_LEAFN_MAGIC || |
| 1408 | save_blk->magic == XFS_ATTR_LEAF_MAGIC); | 1335 | save_blk->magic == XFS_ATTR_LEAF_MAGIC); |
| 1409 | ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); | 1336 | ASSERT(save_blk->magic == be16_to_cpu(save_info->magic)); |
| 1410 | ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); | 1337 | ASSERT(drop_blk->magic == be16_to_cpu(drop_info->magic)); |
| @@ -1529,7 +1456,7 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | |||
| 1529 | ASSERT(blk->bp != NULL); | 1456 | ASSERT(blk->bp != NULL); |
| 1530 | info = blk->bp->data; | 1457 | info = blk->bp->data; |
| 1531 | ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || | 1458 | ASSERT(be16_to_cpu(info->magic) == XFS_DA_NODE_MAGIC || |
| 1532 | be16_to_cpu(info->magic) == XFS_DIRX_LEAF_MAGIC(state->mp) || | 1459 | be16_to_cpu(info->magic) == XFS_DIR2_LEAFN_MAGIC || |
| 1533 | be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); | 1460 | be16_to_cpu(info->magic) == XFS_ATTR_LEAF_MAGIC); |
| 1534 | blk->magic = be16_to_cpu(info->magic); | 1461 | blk->magic = be16_to_cpu(info->magic); |
| 1535 | if (blk->magic == XFS_DA_NODE_MAGIC) { | 1462 | if (blk->magic == XFS_DA_NODE_MAGIC) { |
| @@ -1548,20 +1475,13 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | |||
| 1548 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, | 1475 | blk->hashval = xfs_attr_leaf_lasthash(blk->bp, |
| 1549 | NULL); | 1476 | NULL); |
| 1550 | break; | 1477 | break; |
| 1551 | case XFS_DIR_LEAF_MAGIC: | ||
| 1552 | ASSERT(XFS_DIR_IS_V1(state->mp)); | ||
| 1553 | blk->hashval = xfs_dir_leaf_lasthash(blk->bp, | ||
| 1554 | NULL); | ||
| 1555 | break; | ||
| 1556 | case XFS_DIR2_LEAFN_MAGIC: | 1478 | case XFS_DIR2_LEAFN_MAGIC: |
| 1557 | ASSERT(XFS_DIR_IS_V2(state->mp)); | ||
| 1558 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, | 1479 | blk->hashval = xfs_dir2_leafn_lasthash(blk->bp, |
| 1559 | NULL); | 1480 | NULL); |
| 1560 | break; | 1481 | break; |
| 1561 | default: | 1482 | default: |
| 1562 | ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || | 1483 | ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC || |
| 1563 | blk->magic == | 1484 | blk->magic == XFS_DIR2_LEAFN_MAGIC); |
| 1564 | XFS_DIRX_LEAF_MAGIC(state->mp)); | ||
| 1565 | break; | 1485 | break; |
| 1566 | } | 1486 | } |
| 1567 | } | 1487 | } |
| @@ -1620,7 +1540,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
| 1620 | xfs_bmbt_irec_t *mapp; | 1540 | xfs_bmbt_irec_t *mapp; |
| 1621 | xfs_inode_t *dp; | 1541 | xfs_inode_t *dp; |
| 1622 | int nmap, error, w, count, c, got, i, mapi; | 1542 | int nmap, error, w, count, c, got, i, mapi; |
| 1623 | xfs_fsize_t size; | ||
| 1624 | xfs_trans_t *tp; | 1543 | xfs_trans_t *tp; |
| 1625 | xfs_mount_t *mp; | 1544 | xfs_mount_t *mp; |
| 1626 | 1545 | ||
| @@ -1631,7 +1550,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
| 1631 | /* | 1550 | /* |
| 1632 | * For new directories adjust the file offset and block count. | 1551 | * For new directories adjust the file offset and block count. |
| 1633 | */ | 1552 | */ |
| 1634 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) { | 1553 | if (w == XFS_DATA_FORK) { |
| 1635 | bno = mp->m_dirleafblk; | 1554 | bno = mp->m_dirleafblk; |
| 1636 | count = mp->m_dirblkfsbs; | 1555 | count = mp->m_dirblkfsbs; |
| 1637 | } else { | 1556 | } else { |
| @@ -1641,10 +1560,9 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
| 1641 | /* | 1560 | /* |
| 1642 | * Find a spot in the file space to put the new block. | 1561 | * Find a spot in the file space to put the new block. |
| 1643 | */ | 1562 | */ |
| 1644 | if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) { | 1563 | if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, w))) |
| 1645 | return error; | 1564 | return error; |
| 1646 | } | 1565 | if (w == XFS_DATA_FORK) |
| 1647 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) | ||
| 1648 | ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); | 1566 | ASSERT(bno >= mp->m_dirleafblk && bno < mp->m_dirfreeblk); |
| 1649 | /* | 1567 | /* |
| 1650 | * Try mapping it in one filesystem block. | 1568 | * Try mapping it in one filesystem block. |
| @@ -1706,19 +1624,6 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno) | |||
| 1706 | if (mapp != &map) | 1624 | if (mapp != &map) |
| 1707 | kmem_free(mapp, sizeof(*mapp) * count); | 1625 | kmem_free(mapp, sizeof(*mapp) * count); |
| 1708 | *new_blkno = (xfs_dablk_t)bno; | 1626 | *new_blkno = (xfs_dablk_t)bno; |
| 1709 | /* | ||
| 1710 | * For version 1 directories, adjust the file size if it changed. | ||
| 1711 | */ | ||
| 1712 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { | ||
| 1713 | ASSERT(mapi == 1); | ||
| 1714 | if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) | ||
| 1715 | return error; | ||
| 1716 | size = XFS_FSB_TO_B(mp, bno); | ||
| 1717 | if (size != dp->i_d.di_size) { | ||
| 1718 | dp->i_d.di_size = size; | ||
| 1719 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | ||
| 1720 | } | ||
| 1721 | } | ||
| 1722 | return 0; | 1627 | return 0; |
| 1723 | } | 1628 | } |
| 1724 | 1629 | ||
| @@ -1743,7 +1648,6 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
| 1743 | int error, w, entno, level, dead_level; | 1648 | int error, w, entno, level, dead_level; |
| 1744 | xfs_da_blkinfo_t *dead_info, *sib_info; | 1649 | xfs_da_blkinfo_t *dead_info, *sib_info; |
| 1745 | xfs_da_intnode_t *par_node, *dead_node; | 1650 | xfs_da_intnode_t *par_node, *dead_node; |
| 1746 | xfs_dir_leafblock_t *dead_leaf; | ||
| 1747 | xfs_dir2_leaf_t *dead_leaf2; | 1651 | xfs_dir2_leaf_t *dead_leaf2; |
| 1748 | xfs_dahash_t dead_hash; | 1652 | xfs_dahash_t dead_hash; |
| 1749 | 1653 | ||
| @@ -1754,11 +1658,8 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
| 1754 | w = args->whichfork; | 1658 | w = args->whichfork; |
| 1755 | ASSERT(w == XFS_DATA_FORK); | 1659 | ASSERT(w == XFS_DATA_FORK); |
| 1756 | mp = ip->i_mount; | 1660 | mp = ip->i_mount; |
| 1757 | if (XFS_DIR_IS_V2(mp)) { | 1661 | lastoff = mp->m_dirfreeblk; |
| 1758 | lastoff = mp->m_dirfreeblk; | 1662 | error = xfs_bmap_last_before(tp, ip, &lastoff, w); |
| 1759 | error = xfs_bmap_last_before(tp, ip, &lastoff, w); | ||
| 1760 | } else | ||
| 1761 | error = xfs_bmap_last_offset(tp, ip, &lastoff, w); | ||
| 1762 | if (error) | 1663 | if (error) |
| 1763 | return error; | 1664 | return error; |
| 1764 | if (unlikely(lastoff == 0)) { | 1665 | if (unlikely(lastoff == 0)) { |
| @@ -1781,14 +1682,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
| 1781 | /* | 1682 | /* |
| 1782 | * Get values from the moved block. | 1683 | * Get values from the moved block. |
| 1783 | */ | 1684 | */ |
| 1784 | if (be16_to_cpu(dead_info->magic) == XFS_DIR_LEAF_MAGIC) { | 1685 | if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) { |
| 1785 | ASSERT(XFS_DIR_IS_V1(mp)); | ||
| 1786 | dead_leaf = (xfs_dir_leafblock_t *)dead_info; | ||
| 1787 | dead_level = 0; | ||
| 1788 | dead_hash = be32_to_cpu(dead_leaf->entries[ | ||
| 1789 | be16_to_cpu(dead_leaf->hdr.count) - 1].hashval); | ||
| 1790 | } else if (be16_to_cpu(dead_info->magic) == XFS_DIR2_LEAFN_MAGIC) { | ||
| 1791 | ASSERT(XFS_DIR_IS_V2(mp)); | ||
| 1792 | dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; | 1686 | dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; |
| 1793 | dead_level = 0; | 1687 | dead_level = 0; |
| 1794 | dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); | 1688 | dead_hash = be32_to_cpu(dead_leaf2->ents[be16_to_cpu(dead_leaf2->hdr.count) - 1].hashval); |
| @@ -1843,7 +1737,7 @@ xfs_da_swap_lastblock(xfs_da_args_t *args, xfs_dablk_t *dead_blknop, | |||
| 1843 | xfs_da_buf_done(sib_buf); | 1737 | xfs_da_buf_done(sib_buf); |
| 1844 | sib_buf = NULL; | 1738 | sib_buf = NULL; |
| 1845 | } | 1739 | } |
| 1846 | par_blkno = XFS_DIR_IS_V1(mp) ? 0 : mp->m_dirleafblk; | 1740 | par_blkno = mp->m_dirleafblk; |
| 1847 | level = -1; | 1741 | level = -1; |
| 1848 | /* | 1742 | /* |
| 1849 | * Walk down the tree looking for the parent of the moved block. | 1743 | * Walk down the tree looking for the parent of the moved block. |
| @@ -1942,8 +1836,6 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | |||
| 1942 | { | 1836 | { |
| 1943 | xfs_inode_t *dp; | 1837 | xfs_inode_t *dp; |
| 1944 | int done, error, w, count; | 1838 | int done, error, w, count; |
| 1945 | xfs_fileoff_t bno; | ||
| 1946 | xfs_fsize_t size; | ||
| 1947 | xfs_trans_t *tp; | 1839 | xfs_trans_t *tp; |
| 1948 | xfs_mount_t *mp; | 1840 | xfs_mount_t *mp; |
| 1949 | 1841 | ||
| @@ -1951,7 +1843,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | |||
| 1951 | w = args->whichfork; | 1843 | w = args->whichfork; |
| 1952 | tp = args->trans; | 1844 | tp = args->trans; |
| 1953 | mp = dp->i_mount; | 1845 | mp = dp->i_mount; |
| 1954 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) | 1846 | if (w == XFS_DATA_FORK) |
| 1955 | count = mp->m_dirblkfsbs; | 1847 | count = mp->m_dirblkfsbs; |
| 1956 | else | 1848 | else |
| 1957 | count = 1; | 1849 | count = 1; |
| @@ -1965,31 +1857,14 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, | |||
| 1965 | 0, args->firstblock, args->flist, NULL, | 1857 | 0, args->firstblock, args->flist, NULL, |
| 1966 | &done)) == ENOSPC) { | 1858 | &done)) == ENOSPC) { |
| 1967 | if (w != XFS_DATA_FORK) | 1859 | if (w != XFS_DATA_FORK) |
| 1968 | goto done; | 1860 | break; |
| 1969 | if ((error = xfs_da_swap_lastblock(args, &dead_blkno, | 1861 | if ((error = xfs_da_swap_lastblock(args, &dead_blkno, |
| 1970 | &dead_buf))) | 1862 | &dead_buf))) |
| 1971 | goto done; | 1863 | break; |
| 1972 | } else if (error) | 1864 | } else { |
| 1973 | goto done; | ||
| 1974 | else | ||
| 1975 | break; | 1865 | break; |
| 1976 | } | ||
| 1977 | ASSERT(done); | ||
| 1978 | xfs_da_binval(tp, dead_buf); | ||
| 1979 | /* | ||
| 1980 | * Adjust the directory size for version 1. | ||
| 1981 | */ | ||
| 1982 | if (w == XFS_DATA_FORK && XFS_DIR_IS_V1(mp)) { | ||
| 1983 | if ((error = xfs_bmap_last_offset(tp, dp, &bno, w))) | ||
| 1984 | return error; | ||
| 1985 | size = XFS_FSB_TO_B(dp->i_mount, bno); | ||
| 1986 | if (size != dp->i_d.di_size) { | ||
| 1987 | dp->i_d.di_size = size; | ||
| 1988 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | ||
| 1989 | } | 1866 | } |
| 1990 | } | 1867 | } |
| 1991 | return 0; | ||
| 1992 | done: | ||
| 1993 | xfs_da_binval(tp, dead_buf); | 1868 | xfs_da_binval(tp, dead_buf); |
| 1994 | return error; | 1869 | return error; |
| 1995 | } | 1870 | } |
| @@ -2050,10 +1925,7 @@ xfs_da_do_buf( | |||
| 2050 | xfs_dabuf_t *rbp; | 1925 | xfs_dabuf_t *rbp; |
| 2051 | 1926 | ||
| 2052 | mp = dp->i_mount; | 1927 | mp = dp->i_mount; |
| 2053 | if (whichfork == XFS_DATA_FORK && XFS_DIR_IS_V2(mp)) | 1928 | nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; |
| 2054 | nfsb = mp->m_dirblkfsbs; | ||
| 2055 | else | ||
| 2056 | nfsb = 1; | ||
| 2057 | mappedbno = *mappedbnop; | 1929 | mappedbno = *mappedbnop; |
| 2058 | /* | 1930 | /* |
| 2059 | * Caller doesn't have a mapping. -2 means don't complain | 1931 | * Caller doesn't have a mapping. -2 means don't complain |
| @@ -2199,7 +2071,6 @@ xfs_da_do_buf( | |||
| 2199 | magic1 = be32_to_cpu(data->hdr.magic); | 2071 | magic1 = be32_to_cpu(data->hdr.magic); |
| 2200 | if (unlikely( | 2072 | if (unlikely( |
| 2201 | XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && | 2073 | XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && |
| 2202 | (magic != XFS_DIR_LEAF_MAGIC) && | ||
| 2203 | (magic != XFS_ATTR_LEAF_MAGIC) && | 2074 | (magic != XFS_ATTR_LEAF_MAGIC) && |
| 2204 | (magic != XFS_DIR2_LEAF1_MAGIC) && | 2075 | (magic != XFS_DIR2_LEAF1_MAGIC) && |
| 2205 | (magic != XFS_DIR2_LEAFN_MAGIC) && | 2076 | (magic != XFS_DIR2_LEAFN_MAGIC) && |
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index 243a730d5ec8..4ab865ec8b82 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h | |||
| @@ -36,14 +36,10 @@ struct zone; | |||
| 36 | * level in the Btree, and to identify which type of block this is. | 36 | * level in the Btree, and to identify which type of block this is. |
| 37 | */ | 37 | */ |
| 38 | #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ | 38 | #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */ |
| 39 | #define XFS_DIR_LEAF_MAGIC 0xfeeb /* magic number: directory leaf blks */ | ||
| 40 | #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ | 39 | #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */ |
| 41 | #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ | 40 | #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */ |
| 42 | #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ | 41 | #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: v2 dirlf multi blks */ |
| 43 | 42 | ||
| 44 | #define XFS_DIRX_LEAF_MAGIC(mp) \ | ||
| 45 | (XFS_DIR_IS_V1(mp) ? XFS_DIR_LEAF_MAGIC : XFS_DIR2_LEAFN_MAGIC) | ||
| 46 | |||
| 47 | typedef struct xfs_da_blkinfo { | 43 | typedef struct xfs_da_blkinfo { |
| 48 | __be32 forw; /* previous block in list */ | 44 | __be32 forw; /* previous block in list */ |
| 49 | __be32 back; /* following block in list */ | 45 | __be32 back; /* following block in list */ |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 29a6c866f2c3..80562b60fb95 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.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" |
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index 77d537782586..b33826961c45 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h | |||
| @@ -85,7 +85,6 @@ typedef struct xfs_dinode | |||
| 85 | union { | 85 | union { |
| 86 | xfs_bmdr_block_t di_bmbt; /* btree root block */ | 86 | xfs_bmdr_block_t di_bmbt; /* btree root block */ |
| 87 | xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ | 87 | xfs_bmbt_rec_32_t di_bmx[1]; /* extent list */ |
| 88 | xfs_dir_shortform_t di_dirsf; /* shortform directory */ | ||
| 89 | xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ | 88 | xfs_dir2_sf_t di_dir2sf; /* shortform directory v2 */ |
| 90 | char di_c[1]; /* local contents */ | 89 | char di_c[1]; /* local contents */ |
| 91 | xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ | 90 | xfs_dev_t di_dev; /* device for S_IFCHR/S_IFBLK */ |
diff --git a/fs/xfs/xfs_dir.c b/fs/xfs/xfs_dir.c index 3cd8657a81f6..e69de29bb2d1 100644 --- a/fs/xfs/xfs_dir.c +++ b/fs/xfs/xfs_dir.c | |||
| @@ -1,1213 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write the Free Software Foundation, | ||
| 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | #include "xfs.h" | ||
| 19 | #include "xfs_fs.h" | ||
| 20 | #include "xfs_types.h" | ||
| 21 | #include "xfs_log.h" | ||
| 22 | #include "xfs_inum.h" | ||
| 23 | #include "xfs_trans.h" | ||
| 24 | #include "xfs_sb.h" | ||
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dir2.h" | ||
| 27 | #include "xfs_dmapi.h" | ||
| 28 | #include "xfs_mount.h" | ||
| 29 | #include "xfs_da_btree.h" | ||
| 30 | #include "xfs_bmap_btree.h" | ||
| 31 | #include "xfs_alloc_btree.h" | ||
| 32 | #include "xfs_ialloc_btree.h" | ||
| 33 | #include "xfs_alloc.h" | ||
| 34 | #include "xfs_btree.h" | ||
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | ||
| 37 | #include "xfs_attr_sf.h" | ||
| 38 | #include "xfs_dinode.h" | ||
| 39 | #include "xfs_inode.h" | ||
| 40 | #include "xfs_bmap.h" | ||
| 41 | #include "xfs_dir_leaf.h" | ||
| 42 | #include "xfs_error.h" | ||
| 43 | |||
| 44 | /* | ||
| 45 | * xfs_dir.c | ||
| 46 | * | ||
| 47 | * Provide the external interfaces to manage directories. | ||
| 48 | */ | ||
| 49 | |||
| 50 | /*======================================================================== | ||
| 51 | * Function prototypes for the kernel. | ||
| 52 | *========================================================================*/ | ||
| 53 | |||
| 54 | /* | ||
| 55 | * Functions for the dirops interfaces. | ||
| 56 | */ | ||
| 57 | static void xfs_dir_mount(struct xfs_mount *mp); | ||
| 58 | |||
| 59 | static int xfs_dir_isempty(struct xfs_inode *dp); | ||
| 60 | |||
| 61 | static int xfs_dir_init(struct xfs_trans *trans, | ||
| 62 | struct xfs_inode *dir, | ||
| 63 | struct xfs_inode *parent_dir); | ||
| 64 | |||
| 65 | static int xfs_dir_createname(struct xfs_trans *trans, | ||
| 66 | struct xfs_inode *dp, | ||
| 67 | char *name_string, | ||
| 68 | int name_len, | ||
| 69 | xfs_ino_t inode_number, | ||
| 70 | xfs_fsblock_t *firstblock, | ||
| 71 | xfs_bmap_free_t *flist, | ||
| 72 | xfs_extlen_t total); | ||
| 73 | |||
| 74 | static int xfs_dir_lookup(struct xfs_trans *tp, | ||
| 75 | struct xfs_inode *dp, | ||
| 76 | char *name_string, | ||
| 77 | int name_length, | ||
| 78 | xfs_ino_t *inode_number); | ||
| 79 | |||
| 80 | static int xfs_dir_removename(struct xfs_trans *trans, | ||
| 81 | struct xfs_inode *dp, | ||
| 82 | char *name_string, | ||
| 83 | int name_length, | ||
| 84 | xfs_ino_t ino, | ||
| 85 | xfs_fsblock_t *firstblock, | ||
| 86 | xfs_bmap_free_t *flist, | ||
| 87 | xfs_extlen_t total); | ||
| 88 | |||
| 89 | static int xfs_dir_getdents(struct xfs_trans *tp, | ||
| 90 | struct xfs_inode *dp, | ||
| 91 | struct uio *uiop, | ||
| 92 | int *eofp); | ||
| 93 | |||
| 94 | static int xfs_dir_replace(struct xfs_trans *tp, | ||
| 95 | struct xfs_inode *dp, | ||
| 96 | char *name_string, | ||
| 97 | int name_length, | ||
| 98 | xfs_ino_t inode_number, | ||
| 99 | xfs_fsblock_t *firstblock, | ||
| 100 | xfs_bmap_free_t *flist, | ||
| 101 | xfs_extlen_t total); | ||
| 102 | |||
| 103 | static int xfs_dir_canenter(struct xfs_trans *tp, | ||
| 104 | struct xfs_inode *dp, | ||
| 105 | char *name_string, | ||
| 106 | int name_length); | ||
| 107 | |||
| 108 | static int xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, | ||
| 109 | xfs_dinode_t *dip); | ||
| 110 | |||
| 111 | xfs_dirops_t xfsv1_dirops = { | ||
| 112 | .xd_mount = xfs_dir_mount, | ||
| 113 | .xd_isempty = xfs_dir_isempty, | ||
| 114 | .xd_init = xfs_dir_init, | ||
| 115 | .xd_createname = xfs_dir_createname, | ||
| 116 | .xd_lookup = xfs_dir_lookup, | ||
| 117 | .xd_removename = xfs_dir_removename, | ||
| 118 | .xd_getdents = xfs_dir_getdents, | ||
| 119 | .xd_replace = xfs_dir_replace, | ||
| 120 | .xd_canenter = xfs_dir_canenter, | ||
| 121 | .xd_shortform_validate_ondisk = xfs_dir_shortform_validate_ondisk, | ||
| 122 | .xd_shortform_to_single = xfs_dir_shortform_to_leaf, | ||
| 123 | }; | ||
| 124 | |||
| 125 | /* | ||
| 126 | * Internal routines when dirsize == XFS_LBSIZE(mp). | ||
| 127 | */ | ||
| 128 | STATIC int xfs_dir_leaf_lookup(xfs_da_args_t *args); | ||
| 129 | STATIC int xfs_dir_leaf_removename(xfs_da_args_t *args, int *number_entries, | ||
| 130 | int *total_namebytes); | ||
| 131 | STATIC int xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, | ||
| 132 | uio_t *uio, int *eofp, | ||
| 133 | xfs_dirent_t *dbp, | ||
| 134 | xfs_dir_put_t put); | ||
| 135 | STATIC int xfs_dir_leaf_replace(xfs_da_args_t *args); | ||
| 136 | |||
| 137 | /* | ||
| 138 | * Internal routines when dirsize > XFS_LBSIZE(mp). | ||
| 139 | */ | ||
| 140 | STATIC int xfs_dir_node_addname(xfs_da_args_t *args); | ||
| 141 | STATIC int xfs_dir_node_lookup(xfs_da_args_t *args); | ||
| 142 | STATIC int xfs_dir_node_removename(xfs_da_args_t *args); | ||
| 143 | STATIC int xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, | ||
| 144 | uio_t *uio, int *eofp, | ||
| 145 | xfs_dirent_t *dbp, | ||
| 146 | xfs_dir_put_t put); | ||
| 147 | STATIC int xfs_dir_node_replace(xfs_da_args_t *args); | ||
| 148 | |||
| 149 | #if defined(XFS_DIR_TRACE) | ||
| 150 | ktrace_t *xfs_dir_trace_buf; | ||
| 151 | #endif | ||
| 152 | |||
| 153 | |||
| 154 | /*======================================================================== | ||
| 155 | * Overall external interface routines. | ||
| 156 | *========================================================================*/ | ||
| 157 | |||
| 158 | xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; | ||
| 159 | |||
| 160 | /* | ||
| 161 | * One-time startup routine called from xfs_init(). | ||
| 162 | */ | ||
| 163 | void | ||
| 164 | xfs_dir_startup(void) | ||
| 165 | { | ||
| 166 | xfs_dir_hash_dot = xfs_da_hashname(".", 1); | ||
| 167 | xfs_dir_hash_dotdot = xfs_da_hashname("..", 2); | ||
| 168 | } | ||
| 169 | |||
| 170 | /* | ||
| 171 | * Initialize directory-related fields in the mount structure. | ||
| 172 | */ | ||
| 173 | static void | ||
| 174 | xfs_dir_mount(xfs_mount_t *mp) | ||
| 175 | { | ||
| 176 | uint shortcount, leafcount, count; | ||
| 177 | |||
| 178 | mp->m_dirversion = 1; | ||
| 179 | if (!(mp->m_flags & XFS_MOUNT_ATTR2)) { | ||
| 180 | shortcount = (mp->m_attroffset - | ||
| 181 | (uint)sizeof(xfs_dir_sf_hdr_t)) / | ||
| 182 | (uint)sizeof(xfs_dir_sf_entry_t); | ||
| 183 | leafcount = (XFS_LBSIZE(mp) - | ||
| 184 | (uint)sizeof(xfs_dir_leaf_hdr_t)) / | ||
| 185 | ((uint)sizeof(xfs_dir_leaf_entry_t) + | ||
| 186 | (uint)sizeof(xfs_dir_leaf_name_t)); | ||
| 187 | } else { | ||
| 188 | shortcount = (XFS_BMDR_SPACE_CALC(MINABTPTRS) - | ||
| 189 | (uint)sizeof(xfs_dir_sf_hdr_t)) / | ||
| 190 | (uint)sizeof(xfs_dir_sf_entry_t); | ||
| 191 | leafcount = (XFS_LBSIZE(mp) - | ||
| 192 | (uint)sizeof(xfs_dir_leaf_hdr_t)) / | ||
| 193 | ((uint)sizeof(xfs_dir_leaf_entry_t) + | ||
| 194 | (uint)sizeof(xfs_dir_leaf_name_t)); | ||
| 195 | } | ||
| 196 | count = shortcount > leafcount ? shortcount : leafcount; | ||
| 197 | mp->m_dircook_elog = xfs_da_log2_roundup(count + 1); | ||
| 198 | ASSERT(mp->m_dircook_elog <= mp->m_sb.sb_blocklog); | ||
| 199 | mp->m_dir_node_ents = mp->m_attr_node_ents = | ||
| 200 | (XFS_LBSIZE(mp) - (uint)sizeof(xfs_da_node_hdr_t)) / | ||
| 201 | (uint)sizeof(xfs_da_node_entry_t); | ||
| 202 | mp->m_dir_magicpct = (XFS_LBSIZE(mp) * 37) / 100; | ||
| 203 | mp->m_dirblksize = mp->m_sb.sb_blocksize; | ||
| 204 | mp->m_dirblkfsbs = 1; | ||
| 205 | } | ||
| 206 | |||
| 207 | /* | ||
| 208 | * Return 1 if directory contains only "." and "..". | ||
| 209 | */ | ||
| 210 | static int | ||
| 211 | xfs_dir_isempty(xfs_inode_t *dp) | ||
| 212 | { | ||
| 213 | xfs_dir_sf_hdr_t *hdr; | ||
| 214 | |||
| 215 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
| 216 | if (dp->i_d.di_size == 0) | ||
| 217 | return(1); | ||
| 218 | if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) | ||
| 219 | return(0); | ||
| 220 | hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data; | ||
| 221 | return(hdr->count == 0); | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 225 | * Initialize a directory with its "." and ".." entries. | ||
| 226 | */ | ||
| 227 | static int | ||
| 228 | xfs_dir_init(xfs_trans_t *trans, xfs_inode_t *dir, xfs_inode_t *parent_dir) | ||
| 229 | { | ||
| 230 | xfs_da_args_t args; | ||
| 231 | int error; | ||
| 232 | |||
| 233 | memset((char *)&args, 0, sizeof(args)); | ||
| 234 | args.dp = dir; | ||
| 235 | args.trans = trans; | ||
| 236 | |||
| 237 | ASSERT((dir->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
| 238 | if ((error = xfs_dir_ino_validate(trans->t_mountp, parent_dir->i_ino))) | ||
| 239 | return error; | ||
| 240 | |||
| 241 | return(xfs_dir_shortform_create(&args, parent_dir->i_ino)); | ||
| 242 | } | ||
| 243 | |||
| 244 | /* | ||
| 245 | * Generic handler routine to add a name to a directory. | ||
| 246 | * Transitions directory from shortform to Btree as necessary. | ||
| 247 | */ | ||
| 248 | static int /* error */ | ||
| 249 | xfs_dir_createname(xfs_trans_t *trans, xfs_inode_t *dp, char *name, | ||
| 250 | int namelen, xfs_ino_t inum, xfs_fsblock_t *firstblock, | ||
| 251 | xfs_bmap_free_t *flist, xfs_extlen_t total) | ||
| 252 | { | ||
| 253 | xfs_da_args_t args; | ||
| 254 | int retval, newsize, done; | ||
| 255 | |||
| 256 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
| 257 | |||
| 258 | if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum))) | ||
| 259 | return (retval); | ||
| 260 | |||
| 261 | XFS_STATS_INC(xs_dir_create); | ||
| 262 | /* | ||
| 263 | * Fill in the arg structure for this request. | ||
| 264 | */ | ||
| 265 | args.name = name; | ||
| 266 | args.namelen = namelen; | ||
| 267 | args.hashval = xfs_da_hashname(name, namelen); | ||
| 268 | args.inumber = inum; | ||
| 269 | args.dp = dp; | ||
| 270 | args.firstblock = firstblock; | ||
| 271 | args.flist = flist; | ||
| 272 | args.total = total; | ||
| 273 | args.whichfork = XFS_DATA_FORK; | ||
| 274 | args.trans = trans; | ||
| 275 | args.justcheck = 0; | ||
| 276 | args.addname = args.oknoent = 1; | ||
| 277 | |||
| 278 | /* | ||
| 279 | * Decide on what work routines to call based on the inode size. | ||
| 280 | */ | ||
| 281 | done = 0; | ||
| 282 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
| 283 | newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen); | ||
| 284 | if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) { | ||
| 285 | retval = xfs_dir_shortform_addname(&args); | ||
| 286 | done = 1; | ||
| 287 | } else { | ||
| 288 | if (total == 0) | ||
| 289 | return XFS_ERROR(ENOSPC); | ||
| 290 | retval = xfs_dir_shortform_to_leaf(&args); | ||
| 291 | done = retval != 0; | ||
| 292 | } | ||
| 293 | } | ||
| 294 | if (!done && xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
| 295 | retval = xfs_dir_leaf_addname(&args); | ||
| 296 | done = retval != ENOSPC; | ||
| 297 | if (!done) { | ||
| 298 | if (total == 0) | ||
| 299 | return XFS_ERROR(ENOSPC); | ||
| 300 | retval = xfs_dir_leaf_to_node(&args); | ||
| 301 | done = retval != 0; | ||
| 302 | } | ||
| 303 | } | ||
| 304 | if (!done) { | ||
| 305 | retval = xfs_dir_node_addname(&args); | ||
| 306 | } | ||
| 307 | return(retval); | ||
| 308 | } | ||
| 309 | |||
| 310 | /* | ||
| 311 | * Generic handler routine to check if a name can be added to a directory, | ||
| 312 | * without adding any blocks to the directory. | ||
| 313 | */ | ||
| 314 | static int /* error */ | ||
| 315 | xfs_dir_canenter(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen) | ||
| 316 | { | ||
| 317 | xfs_da_args_t args; | ||
| 318 | int retval, newsize; | ||
| 319 | |||
| 320 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
| 321 | /* | ||
| 322 | * Fill in the arg structure for this request. | ||
| 323 | */ | ||
| 324 | args.name = name; | ||
| 325 | args.namelen = namelen; | ||
| 326 | args.hashval = xfs_da_hashname(name, namelen); | ||
| 327 | args.inumber = 0; | ||
| 328 | args.dp = dp; | ||
| 329 | args.firstblock = NULL; | ||
| 330 | args.flist = NULL; | ||
| 331 | args.total = 0; | ||
| 332 | args.whichfork = XFS_DATA_FORK; | ||
| 333 | args.trans = trans; | ||
| 334 | args.justcheck = args.addname = args.oknoent = 1; | ||
| 335 | |||
| 336 | /* | ||
| 337 | * Decide on what work routines to call based on the inode size. | ||
| 338 | */ | ||
| 339 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
| 340 | newsize = XFS_DIR_SF_ENTSIZE_BYNAME(args.namelen); | ||
| 341 | if ((dp->i_d.di_size + newsize) <= XFS_IFORK_DSIZE(dp)) | ||
| 342 | retval = 0; | ||
| 343 | else | ||
| 344 | retval = XFS_ERROR(ENOSPC); | ||
| 345 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
| 346 | retval = xfs_dir_leaf_addname(&args); | ||
| 347 | } else { | ||
| 348 | retval = xfs_dir_node_addname(&args); | ||
| 349 | } | ||
| 350 | return(retval); | ||
| 351 | } | ||
| 352 | |||
| 353 | /* | ||
| 354 | * Generic handler routine to remove a name from a directory. | ||
| 355 | * Transitions directory from Btree to shortform as necessary. | ||
| 356 | */ | ||
| 357 | static int /* error */ | ||
| 358 | xfs_dir_removename(xfs_trans_t *trans, xfs_inode_t *dp, char *name, | ||
| 359 | int namelen, xfs_ino_t ino, xfs_fsblock_t *firstblock, | ||
| 360 | xfs_bmap_free_t *flist, xfs_extlen_t total) | ||
| 361 | { | ||
| 362 | xfs_da_args_t args; | ||
| 363 | int count, totallen, newsize, retval; | ||
| 364 | |||
| 365 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
| 366 | XFS_STATS_INC(xs_dir_remove); | ||
| 367 | /* | ||
| 368 | * Fill in the arg structure for this request. | ||
| 369 | */ | ||
| 370 | args.name = name; | ||
| 371 | args.namelen = namelen; | ||
| 372 | args.hashval = xfs_da_hashname(name, namelen); | ||
| 373 | args.inumber = ino; | ||
| 374 | args.dp = dp; | ||
| 375 | args.firstblock = firstblock; | ||
| 376 | args.flist = flist; | ||
| 377 | args.total = total; | ||
| 378 | args.whichfork = XFS_DATA_FORK; | ||
| 379 | args.trans = trans; | ||
| 380 | args.justcheck = args.addname = args.oknoent = 0; | ||
| 381 | |||
| 382 | /* | ||
| 383 | * Decide on what work routines to call based on the inode size. | ||
| 384 | */ | ||
| 385 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
| 386 | retval = xfs_dir_shortform_removename(&args); | ||
| 387 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
| 388 | retval = xfs_dir_leaf_removename(&args, &count, &totallen); | ||
| 389 | if (retval == 0) { | ||
| 390 | newsize = XFS_DIR_SF_ALLFIT(count, totallen); | ||
| 391 | if (newsize <= XFS_IFORK_DSIZE(dp)) { | ||
| 392 | retval = xfs_dir_leaf_to_shortform(&args); | ||
| 393 | } | ||
| 394 | } | ||
| 395 | } else { | ||
| 396 | retval = xfs_dir_node_removename(&args); | ||
| 397 | } | ||
| 398 | return(retval); | ||
| 399 | } | ||
| 400 | |||
| 401 | static int /* error */ | ||
| 402 | xfs_dir_lookup(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen, | ||
| 403 | xfs_ino_t *inum) | ||
| 404 | { | ||
| 405 | xfs_da_args_t args; | ||
| 406 | int retval; | ||
| 407 | |||
| 408 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
| 409 | |||
| 410 | XFS_STATS_INC(xs_dir_lookup); | ||
| 411 | /* | ||
| 412 | * Fill in the arg structure for this request. | ||
| 413 | */ | ||
| 414 | args.name = name; | ||
| 415 | args.namelen = namelen; | ||
| 416 | args.hashval = xfs_da_hashname(name, namelen); | ||
| 417 | args.inumber = 0; | ||
| 418 | args.dp = dp; | ||
| 419 | args.firstblock = NULL; | ||
| 420 | args.flist = NULL; | ||
| 421 | args.total = 0; | ||
| 422 | args.whichfork = XFS_DATA_FORK; | ||
| 423 | args.trans = trans; | ||
| 424 | args.justcheck = args.addname = 0; | ||
| 425 | args.oknoent = 1; | ||
| 426 | |||
| 427 | /* | ||
| 428 | * Decide on what work routines to call based on the inode size. | ||
| 429 | */ | ||
| 430 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
| 431 | retval = xfs_dir_shortform_lookup(&args); | ||
| 432 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
| 433 | retval = xfs_dir_leaf_lookup(&args); | ||
| 434 | } else { | ||
| 435 | retval = xfs_dir_node_lookup(&args); | ||
| 436 | } | ||
| 437 | if (retval == EEXIST) | ||
| 438 | retval = 0; | ||
| 439 | *inum = args.inumber; | ||
| 440 | return(retval); | ||
| 441 | } | ||
| 442 | |||
| 443 | /* | ||
| 444 | * Implement readdir. | ||
| 445 | */ | ||
| 446 | static int /* error */ | ||
| 447 | xfs_dir_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, int *eofp) | ||
| 448 | { | ||
| 449 | xfs_dirent_t *dbp; | ||
| 450 | int alignment, retval; | ||
| 451 | xfs_dir_put_t put; | ||
| 452 | |||
| 453 | XFS_STATS_INC(xs_dir_getdents); | ||
| 454 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
| 455 | |||
| 456 | /* | ||
| 457 | * If our caller has given us a single contiguous memory buffer, | ||
| 458 | * just work directly within that buffer. If it's in user memory, | ||
| 459 | * lock it down first. | ||
| 460 | */ | ||
| 461 | alignment = sizeof(xfs_off_t) - 1; | ||
| 462 | if ((uio->uio_iovcnt == 1) && | ||
| 463 | (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) && | ||
| 464 | ((uio->uio_iov[0].iov_len & alignment) == 0)) { | ||
| 465 | dbp = NULL; | ||
| 466 | put = xfs_dir_put_dirent64_direct; | ||
| 467 | } else { | ||
| 468 | dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP); | ||
| 469 | put = xfs_dir_put_dirent64_uio; | ||
| 470 | } | ||
| 471 | |||
| 472 | /* | ||
| 473 | * Decide on what work routines to call based on the inode size. | ||
| 474 | */ | ||
| 475 | *eofp = 0; | ||
| 476 | |||
| 477 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
| 478 | retval = xfs_dir_shortform_getdents(dp, uio, eofp, dbp, put); | ||
| 479 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
| 480 | retval = xfs_dir_leaf_getdents(trans, dp, uio, eofp, dbp, put); | ||
| 481 | } else { | ||
| 482 | retval = xfs_dir_node_getdents(trans, dp, uio, eofp, dbp, put); | ||
| 483 | } | ||
| 484 | if (dbp != NULL) | ||
| 485 | kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN); | ||
| 486 | |||
| 487 | return(retval); | ||
| 488 | } | ||
| 489 | |||
| 490 | static int /* error */ | ||
| 491 | xfs_dir_replace(xfs_trans_t *trans, xfs_inode_t *dp, char *name, int namelen, | ||
| 492 | xfs_ino_t inum, xfs_fsblock_t *firstblock, | ||
| 493 | xfs_bmap_free_t *flist, xfs_extlen_t total) | ||
| 494 | { | ||
| 495 | xfs_da_args_t args; | ||
| 496 | int retval; | ||
| 497 | |||
| 498 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | ||
| 499 | |||
| 500 | if ((retval = xfs_dir_ino_validate(trans->t_mountp, inum))) | ||
| 501 | return retval; | ||
| 502 | |||
| 503 | /* | ||
| 504 | * Fill in the arg structure for this request. | ||
| 505 | */ | ||
| 506 | args.name = name; | ||
| 507 | args.namelen = namelen; | ||
| 508 | args.hashval = xfs_da_hashname(name, namelen); | ||
| 509 | args.inumber = inum; | ||
| 510 | args.dp = dp; | ||
| 511 | args.firstblock = firstblock; | ||
| 512 | args.flist = flist; | ||
| 513 | args.total = total; | ||
| 514 | args.whichfork = XFS_DATA_FORK; | ||
| 515 | args.trans = trans; | ||
| 516 | args.justcheck = args.addname = args.oknoent = 0; | ||
| 517 | |||
| 518 | /* | ||
| 519 | * Decide on what work routines to call based on the inode size. | ||
| 520 | */ | ||
| 521 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { | ||
| 522 | retval = xfs_dir_shortform_replace(&args); | ||
| 523 | } else if (xfs_bmap_one_block(dp, XFS_DATA_FORK)) { | ||
| 524 | retval = xfs_dir_leaf_replace(&args); | ||
| 525 | } else { | ||
| 526 | retval = xfs_dir_node_replace(&args); | ||
| 527 | } | ||
| 528 | |||
| 529 | return(retval); | ||
| 530 | } | ||
| 531 | |||
| 532 | static int | ||
| 533 | xfs_dir_shortform_validate_ondisk(xfs_mount_t *mp, xfs_dinode_t *dp) | ||
| 534 | { | ||
| 535 | xfs_ino_t ino; | ||
| 536 | int namelen_sum; | ||
| 537 | int count; | ||
| 538 | xfs_dir_shortform_t *sf; | ||
| 539 | xfs_dir_sf_entry_t *sfe; | ||
| 540 | int i; | ||
| 541 | |||
| 542 | |||
| 543 | |||
| 544 | if ((INT_GET(dp->di_core.di_mode, ARCH_CONVERT) & S_IFMT) != S_IFDIR) { | ||
| 545 | return 0; | ||
| 546 | } | ||
| 547 | if (INT_GET(dp->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_LOCAL) { | ||
| 548 | return 0; | ||
| 549 | } | ||
| 550 | if (INT_GET(dp->di_core.di_size, ARCH_CONVERT) < sizeof(sf->hdr)) { | ||
| 551 | xfs_fs_cmn_err(CE_WARN, mp, "Invalid shortform size: dp 0x%p", | ||
| 552 | dp); | ||
| 553 | return 1; | ||
| 554 | } | ||
| 555 | sf = (xfs_dir_shortform_t *)(&dp->di_u.di_dirsf); | ||
| 556 | ino = XFS_GET_DIR_INO8(sf->hdr.parent); | ||
| 557 | if (xfs_dir_ino_validate(mp, ino)) | ||
| 558 | return 1; | ||
| 559 | |||
| 560 | count = sf->hdr.count; | ||
| 561 | if ((count < 0) || ((count * 10) > XFS_LITINO(mp))) { | ||
| 562 | xfs_fs_cmn_err(CE_WARN, mp, | ||
| 563 | "Invalid shortform count: dp 0x%p", dp); | ||
| 564 | return(1); | ||
| 565 | } | ||
| 566 | |||
| 567 | if (count == 0) { | ||
| 568 | return 0; | ||
| 569 | } | ||
| 570 | |||
| 571 | namelen_sum = 0; | ||
| 572 | sfe = &sf->list[0]; | ||
| 573 | for (i = sf->hdr.count - 1; i >= 0; i--) { | ||
| 574 | ino = XFS_GET_DIR_INO8(sfe->inumber); | ||
| 575 | xfs_dir_ino_validate(mp, ino); | ||
| 576 | if (sfe->namelen >= XFS_LITINO(mp)) { | ||
| 577 | xfs_fs_cmn_err(CE_WARN, mp, | ||
| 578 | "Invalid shortform namelen: dp 0x%p", dp); | ||
| 579 | return 1; | ||
| 580 | } | ||
| 581 | namelen_sum += sfe->namelen; | ||
| 582 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
| 583 | } | ||
| 584 | if (namelen_sum >= XFS_LITINO(mp)) { | ||
| 585 | xfs_fs_cmn_err(CE_WARN, mp, | ||
| 586 | "Invalid shortform namelen: dp 0x%p", dp); | ||
| 587 | return 1; | ||
| 588 | } | ||
| 589 | |||
| 590 | return 0; | ||
| 591 | } | ||
| 592 | |||
| 593 | /*======================================================================== | ||
| 594 | * External routines when dirsize == XFS_LBSIZE(dp->i_mount). | ||
| 595 | *========================================================================*/ | ||
| 596 | |||
| 597 | /* | ||
| 598 | * Add a name to the leaf directory structure | ||
| 599 | * This is the external routine. | ||
| 600 | */ | ||
| 601 | int | ||
| 602 | xfs_dir_leaf_addname(xfs_da_args_t *args) | ||
| 603 | { | ||
| 604 | int index, retval; | ||
| 605 | xfs_dabuf_t *bp; | ||
| 606 | |||
| 607 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, | ||
| 608 | XFS_DATA_FORK); | ||
| 609 | if (retval) | ||
| 610 | return(retval); | ||
| 611 | ASSERT(bp != NULL); | ||
| 612 | |||
| 613 | retval = xfs_dir_leaf_lookup_int(bp, args, &index); | ||
| 614 | if (retval == ENOENT) | ||
| 615 | retval = xfs_dir_leaf_add(bp, args, index); | ||
| 616 | xfs_da_buf_done(bp); | ||
| 617 | return(retval); | ||
| 618 | } | ||
| 619 | |||
| 620 | /* | ||
| 621 | * Remove a name from the leaf directory structure | ||
| 622 | * This is the external routine. | ||
| 623 | */ | ||
| 624 | STATIC int | ||
| 625 | xfs_dir_leaf_removename(xfs_da_args_t *args, int *count, int *totallen) | ||
| 626 | { | ||
| 627 | xfs_dir_leafblock_t *leaf; | ||
| 628 | int index, retval; | ||
| 629 | xfs_dabuf_t *bp; | ||
| 630 | |||
| 631 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, | ||
| 632 | XFS_DATA_FORK); | ||
| 633 | if (retval) | ||
| 634 | return(retval); | ||
| 635 | ASSERT(bp != NULL); | ||
| 636 | leaf = bp->data; | ||
| 637 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 638 | retval = xfs_dir_leaf_lookup_int(bp, args, &index); | ||
| 639 | if (retval == EEXIST) { | ||
| 640 | (void)xfs_dir_leaf_remove(args->trans, bp, index); | ||
| 641 | *count = be16_to_cpu(leaf->hdr.count); | ||
| 642 | *totallen = be16_to_cpu(leaf->hdr.namebytes); | ||
| 643 | retval = 0; | ||
| 644 | } | ||
| 645 | xfs_da_buf_done(bp); | ||
| 646 | return(retval); | ||
| 647 | } | ||
| 648 | |||
| 649 | /* | ||
| 650 | * Look up a name in a leaf directory structure. | ||
| 651 | * This is the external routine. | ||
| 652 | */ | ||
| 653 | STATIC int | ||
| 654 | xfs_dir_leaf_lookup(xfs_da_args_t *args) | ||
| 655 | { | ||
| 656 | int index, retval; | ||
| 657 | xfs_dabuf_t *bp; | ||
| 658 | |||
| 659 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, | ||
| 660 | XFS_DATA_FORK); | ||
| 661 | if (retval) | ||
| 662 | return(retval); | ||
| 663 | ASSERT(bp != NULL); | ||
| 664 | retval = xfs_dir_leaf_lookup_int(bp, args, &index); | ||
| 665 | xfs_da_brelse(args->trans, bp); | ||
| 666 | return(retval); | ||
| 667 | } | ||
| 668 | |||
| 669 | /* | ||
| 670 | * Copy out directory entries for getdents(), for leaf directories. | ||
| 671 | */ | ||
| 672 | STATIC int | ||
| 673 | xfs_dir_leaf_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, | ||
| 674 | int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put) | ||
| 675 | { | ||
| 676 | xfs_dabuf_t *bp; | ||
| 677 | int retval, eob; | ||
| 678 | |||
| 679 | retval = xfs_da_read_buf(dp->i_transp, dp, 0, -1, &bp, XFS_DATA_FORK); | ||
| 680 | if (retval) | ||
| 681 | return(retval); | ||
| 682 | ASSERT(bp != NULL); | ||
| 683 | retval = xfs_dir_leaf_getdents_int(bp, dp, 0, uio, &eob, dbp, put, -1); | ||
| 684 | xfs_da_brelse(trans, bp); | ||
| 685 | *eofp = (eob == 0); | ||
| 686 | return(retval); | ||
| 687 | } | ||
| 688 | |||
| 689 | /* | ||
| 690 | * Look up a name in a leaf directory structure, replace the inode number. | ||
| 691 | * This is the external routine. | ||
| 692 | */ | ||
| 693 | STATIC int | ||
| 694 | xfs_dir_leaf_replace(xfs_da_args_t *args) | ||
| 695 | { | ||
| 696 | int index, retval; | ||
| 697 | xfs_dabuf_t *bp; | ||
| 698 | xfs_ino_t inum; | ||
| 699 | xfs_dir_leafblock_t *leaf; | ||
| 700 | xfs_dir_leaf_entry_t *entry; | ||
| 701 | xfs_dir_leaf_name_t *namest; | ||
| 702 | |||
| 703 | inum = args->inumber; | ||
| 704 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp, | ||
| 705 | XFS_DATA_FORK); | ||
| 706 | if (retval) | ||
| 707 | return(retval); | ||
| 708 | ASSERT(bp != NULL); | ||
| 709 | retval = xfs_dir_leaf_lookup_int(bp, args, &index); | ||
| 710 | if (retval == EEXIST) { | ||
| 711 | leaf = bp->data; | ||
| 712 | entry = &leaf->entries[index]; | ||
| 713 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); | ||
| 714 | /* XXX - replace assert? */ | ||
| 715 | XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber); | ||
| 716 | xfs_da_log_buf(args->trans, bp, | ||
| 717 | XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber))); | ||
| 718 | xfs_da_buf_done(bp); | ||
| 719 | retval = 0; | ||
| 720 | } else | ||
| 721 | xfs_da_brelse(args->trans, bp); | ||
| 722 | return(retval); | ||
| 723 | } | ||
| 724 | |||
| 725 | |||
| 726 | /*======================================================================== | ||
| 727 | * External routines when dirsize > XFS_LBSIZE(mp). | ||
| 728 | *========================================================================*/ | ||
| 729 | |||
| 730 | /* | ||
| 731 | * Add a name to a Btree-format directory. | ||
| 732 | * | ||
| 733 | * This will involve walking down the Btree, and may involve splitting | ||
| 734 | * leaf nodes and even splitting intermediate nodes up to and including | ||
| 735 | * the root node (a special case of an intermediate node). | ||
| 736 | */ | ||
| 737 | STATIC int | ||
| 738 | xfs_dir_node_addname(xfs_da_args_t *args) | ||
| 739 | { | ||
| 740 | xfs_da_state_t *state; | ||
| 741 | xfs_da_state_blk_t *blk; | ||
| 742 | int retval, error; | ||
| 743 | |||
| 744 | /* | ||
| 745 | * Fill in bucket of arguments/results/context to carry around. | ||
| 746 | */ | ||
| 747 | state = xfs_da_state_alloc(); | ||
| 748 | state->args = args; | ||
| 749 | state->mp = args->dp->i_mount; | ||
| 750 | state->blocksize = state->mp->m_sb.sb_blocksize; | ||
| 751 | state->node_ents = state->mp->m_dir_node_ents; | ||
| 752 | |||
| 753 | /* | ||
| 754 | * Search to see if name already exists, and get back a pointer | ||
| 755 | * to where it should go. | ||
| 756 | */ | ||
| 757 | error = xfs_da_node_lookup_int(state, &retval); | ||
| 758 | if (error) | ||
| 759 | retval = error; | ||
| 760 | if (retval != ENOENT) | ||
| 761 | goto error; | ||
| 762 | blk = &state->path.blk[ state->path.active-1 ]; | ||
| 763 | ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); | ||
| 764 | retval = xfs_dir_leaf_add(blk->bp, args, blk->index); | ||
| 765 | if (retval == 0) { | ||
| 766 | /* | ||
| 767 | * Addition succeeded, update Btree hashvals. | ||
| 768 | */ | ||
| 769 | if (!args->justcheck) | ||
| 770 | xfs_da_fixhashpath(state, &state->path); | ||
| 771 | } else { | ||
| 772 | /* | ||
| 773 | * Addition failed, split as many Btree elements as required. | ||
| 774 | */ | ||
| 775 | if (args->total == 0) { | ||
| 776 | ASSERT(retval == ENOSPC); | ||
| 777 | goto error; | ||
| 778 | } | ||
| 779 | retval = xfs_da_split(state); | ||
| 780 | } | ||
| 781 | error: | ||
| 782 | xfs_da_state_free(state); | ||
| 783 | |||
| 784 | return(retval); | ||
| 785 | } | ||
| 786 | |||
| 787 | /* | ||
| 788 | * Remove a name from a B-tree directory. | ||
| 789 | * | ||
| 790 | * This will involve walking down the Btree, and may involve joining | ||
| 791 | * leaf nodes and even joining intermediate nodes up to and including | ||
| 792 | * the root node (a special case of an intermediate node). | ||
| 793 | */ | ||
| 794 | STATIC int | ||
| 795 | xfs_dir_node_removename(xfs_da_args_t *args) | ||
| 796 | { | ||
| 797 | xfs_da_state_t *state; | ||
| 798 | xfs_da_state_blk_t *blk; | ||
| 799 | int retval, error; | ||
| 800 | |||
| 801 | state = xfs_da_state_alloc(); | ||
| 802 | state->args = args; | ||
| 803 | state->mp = args->dp->i_mount; | ||
| 804 | state->blocksize = state->mp->m_sb.sb_blocksize; | ||
| 805 | state->node_ents = state->mp->m_dir_node_ents; | ||
| 806 | |||
| 807 | /* | ||
| 808 | * Search to see if name exists, and get back a pointer to it. | ||
| 809 | */ | ||
| 810 | error = xfs_da_node_lookup_int(state, &retval); | ||
| 811 | if (error) | ||
| 812 | retval = error; | ||
| 813 | if (retval != EEXIST) { | ||
| 814 | xfs_da_state_free(state); | ||
| 815 | return(retval); | ||
| 816 | } | ||
| 817 | |||
| 818 | /* | ||
| 819 | * Remove the name and update the hashvals in the tree. | ||
| 820 | */ | ||
| 821 | blk = &state->path.blk[ state->path.active-1 ]; | ||
| 822 | ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); | ||
| 823 | retval = xfs_dir_leaf_remove(args->trans, blk->bp, blk->index); | ||
| 824 | xfs_da_fixhashpath(state, &state->path); | ||
| 825 | |||
| 826 | /* | ||
| 827 | * Check to see if the tree needs to be collapsed. | ||
| 828 | */ | ||
| 829 | error = 0; | ||
| 830 | if (retval) { | ||
| 831 | error = xfs_da_join(state); | ||
| 832 | } | ||
| 833 | |||
| 834 | xfs_da_state_free(state); | ||
| 835 | if (error) | ||
| 836 | return(error); | ||
| 837 | return(0); | ||
| 838 | } | ||
| 839 | |||
| 840 | /* | ||
| 841 | * Look up a filename in a int directory. | ||
| 842 | * Use an internal routine to actually do all the work. | ||
| 843 | */ | ||
| 844 | STATIC int | ||
| 845 | xfs_dir_node_lookup(xfs_da_args_t *args) | ||
| 846 | { | ||
| 847 | xfs_da_state_t *state; | ||
| 848 | int retval, error, i; | ||
| 849 | |||
| 850 | state = xfs_da_state_alloc(); | ||
| 851 | state->args = args; | ||
| 852 | state->mp = args->dp->i_mount; | ||
| 853 | state->blocksize = state->mp->m_sb.sb_blocksize; | ||
| 854 | state->node_ents = state->mp->m_dir_node_ents; | ||
| 855 | |||
| 856 | /* | ||
| 857 | * Search to see if name exists, | ||
| 858 | * and get back a pointer to it. | ||
| 859 | */ | ||
| 860 | error = xfs_da_node_lookup_int(state, &retval); | ||
| 861 | if (error) { | ||
| 862 | retval = error; | ||
| 863 | } | ||
| 864 | |||
| 865 | /* | ||
| 866 | * If not in a transaction, we have to release all the buffers. | ||
| 867 | */ | ||
| 868 | for (i = 0; i < state->path.active; i++) { | ||
| 869 | xfs_da_brelse(args->trans, state->path.blk[i].bp); | ||
| 870 | state->path.blk[i].bp = NULL; | ||
| 871 | } | ||
| 872 | |||
| 873 | xfs_da_state_free(state); | ||
| 874 | return(retval); | ||
| 875 | } | ||
| 876 | |||
| 877 | STATIC int | ||
| 878 | xfs_dir_node_getdents(xfs_trans_t *trans, xfs_inode_t *dp, uio_t *uio, | ||
| 879 | int *eofp, xfs_dirent_t *dbp, xfs_dir_put_t put) | ||
| 880 | { | ||
| 881 | xfs_da_intnode_t *node; | ||
| 882 | xfs_da_node_entry_t *btree; | ||
| 883 | xfs_dir_leafblock_t *leaf = NULL; | ||
| 884 | xfs_dablk_t bno, nextbno; | ||
| 885 | xfs_dahash_t cookhash; | ||
| 886 | xfs_mount_t *mp; | ||
| 887 | int error, eob, i; | ||
| 888 | xfs_dabuf_t *bp; | ||
| 889 | xfs_daddr_t nextda; | ||
| 890 | |||
| 891 | /* | ||
| 892 | * Pick up our context. | ||
| 893 | */ | ||
| 894 | mp = dp->i_mount; | ||
| 895 | bp = NULL; | ||
| 896 | bno = XFS_DA_COOKIE_BNO(mp, uio->uio_offset); | ||
| 897 | cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset); | ||
| 898 | |||
| 899 | xfs_dir_trace_g_du("node: start", dp, uio); | ||
| 900 | |||
| 901 | /* | ||
| 902 | * Re-find our place, even if we're confused about what our place is. | ||
| 903 | * | ||
| 904 | * First we check the block number from the magic cookie, it is a | ||
| 905 | * cache of where we ended last time. If we find a leaf block, and | ||
| 906 | * the starting hashval in that block is less than our desired | ||
| 907 | * hashval, then we run with it. | ||
| 908 | */ | ||
| 909 | if (bno > 0) { | ||
| 910 | error = xfs_da_read_buf(trans, dp, bno, -2, &bp, XFS_DATA_FORK); | ||
| 911 | if ((error != 0) && (error != EFSCORRUPTED)) | ||
| 912 | return(error); | ||
| 913 | if (bp) | ||
| 914 | leaf = bp->data; | ||
| 915 | if (bp && be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { | ||
| 916 | xfs_dir_trace_g_dub("node: block not a leaf", | ||
| 917 | dp, uio, bno); | ||
| 918 | xfs_da_brelse(trans, bp); | ||
| 919 | bp = NULL; | ||
| 920 | } | ||
| 921 | if (bp && be32_to_cpu(leaf->entries[0].hashval) > cookhash) { | ||
| 922 | xfs_dir_trace_g_dub("node: leaf hash too large", | ||
| 923 | dp, uio, bno); | ||
| 924 | xfs_da_brelse(trans, bp); | ||
| 925 | bp = NULL; | ||
| 926 | } | ||
| 927 | if (bp && cookhash > be32_to_cpu(leaf->entries[ | ||
| 928 | be16_to_cpu(leaf->hdr.count) - 1].hashval)) { | ||
| 929 | xfs_dir_trace_g_dub("node: leaf hash too small", | ||
| 930 | dp, uio, bno); | ||
| 931 | xfs_da_brelse(trans, bp); | ||
| 932 | bp = NULL; | ||
| 933 | } | ||
| 934 | } | ||
| 935 | |||
| 936 | /* | ||
| 937 | * If we did not find a leaf block from the blockno in the cookie, | ||
| 938 | * or we there was no blockno in the cookie (eg: first time thru), | ||
| 939 | * the we start at the top of the Btree and re-find our hashval. | ||
| 940 | */ | ||
| 941 | if (bp == NULL) { | ||
| 942 | xfs_dir_trace_g_du("node: start at root" , dp, uio); | ||
| 943 | bno = 0; | ||
| 944 | for (;;) { | ||
| 945 | error = xfs_da_read_buf(trans, dp, bno, -1, &bp, | ||
| 946 | XFS_DATA_FORK); | ||
| 947 | if (error) | ||
| 948 | return(error); | ||
| 949 | if (bp == NULL) | ||
| 950 | return(XFS_ERROR(EFSCORRUPTED)); | ||
| 951 | node = bp->data; | ||
| 952 | if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) | ||
| 953 | break; | ||
| 954 | btree = &node->btree[0]; | ||
| 955 | xfs_dir_trace_g_dun("node: node detail", dp, uio, node); | ||
| 956 | for (i = 0; i < be16_to_cpu(node->hdr.count); btree++, i++) { | ||
| 957 | if (be32_to_cpu(btree->hashval) >= cookhash) { | ||
| 958 | bno = be32_to_cpu(btree->before); | ||
| 959 | break; | ||
| 960 | } | ||
| 961 | } | ||
| 962 | if (i == be16_to_cpu(node->hdr.count)) { | ||
| 963 | xfs_da_brelse(trans, bp); | ||
| 964 | xfs_dir_trace_g_du("node: hash beyond EOF", | ||
| 965 | dp, uio); | ||
| 966 | uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, | ||
| 967 | XFS_DA_MAXHASH); | ||
| 968 | *eofp = 1; | ||
| 969 | return(0); | ||
| 970 | } | ||
| 971 | xfs_dir_trace_g_dub("node: going to block", | ||
| 972 | dp, uio, bno); | ||
| 973 | xfs_da_brelse(trans, bp); | ||
| 974 | } | ||
| 975 | } | ||
| 976 | ASSERT(cookhash != XFS_DA_MAXHASH); | ||
| 977 | |||
| 978 | /* | ||
| 979 | * We've dropped down to the (first) leaf block that contains the | ||
| 980 | * hashval we are interested in. Continue rolling upward thru the | ||
| 981 | * leaf blocks until we fill up our buffer. | ||
| 982 | */ | ||
| 983 | for (;;) { | ||
| 984 | leaf = bp->data; | ||
| 985 | if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC)) { | ||
| 986 | xfs_dir_trace_g_dul("node: not a leaf", dp, uio, leaf); | ||
| 987 | xfs_da_brelse(trans, bp); | ||
| 988 | XFS_CORRUPTION_ERROR("xfs_dir_node_getdents(1)", | ||
| 989 | XFS_ERRLEVEL_LOW, mp, leaf); | ||
| 990 | return XFS_ERROR(EFSCORRUPTED); | ||
| 991 | } | ||
| 992 | xfs_dir_trace_g_dul("node: leaf detail", dp, uio, leaf); | ||
| 993 | if ((nextbno = be32_to_cpu(leaf->hdr.info.forw))) { | ||
| 994 | nextda = xfs_da_reada_buf(trans, dp, nextbno, | ||
| 995 | XFS_DATA_FORK); | ||
| 996 | } else | ||
| 997 | nextda = -1; | ||
| 998 | error = xfs_dir_leaf_getdents_int(bp, dp, bno, uio, &eob, dbp, | ||
| 999 | put, nextda); | ||
| 1000 | xfs_da_brelse(trans, bp); | ||
| 1001 | bno = nextbno; | ||
| 1002 | if (eob) { | ||
| 1003 | xfs_dir_trace_g_dub("node: E-O-B", dp, uio, bno); | ||
| 1004 | *eofp = 0; | ||
| 1005 | return(error); | ||
| 1006 | } | ||
| 1007 | if (bno == 0) | ||
| 1008 | break; | ||
| 1009 | error = xfs_da_read_buf(trans, dp, bno, nextda, &bp, | ||
| 1010 | XFS_DATA_FORK); | ||
| 1011 | if (error) | ||
| 1012 | return(error); | ||
| 1013 | if (unlikely(bp == NULL)) { | ||
| 1014 | XFS_ERROR_REPORT("xfs_dir_node_getdents(2)", | ||
| 1015 | XFS_ERRLEVEL_LOW, mp); | ||
| 1016 | return(XFS_ERROR(EFSCORRUPTED)); | ||
| 1017 | } | ||
| 1018 | } | ||
| 1019 | *eofp = 1; | ||
| 1020 | xfs_dir_trace_g_du("node: E-O-F", dp, uio); | ||
| 1021 | return(0); | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | /* | ||
| 1025 | * Look up a filename in an int directory, replace the inode number. | ||
| 1026 | * Use an internal routine to actually do the lookup. | ||
| 1027 | */ | ||
| 1028 | STATIC int | ||
| 1029 | xfs_dir_node_replace(xfs_da_args_t *args) | ||
| 1030 | { | ||
| 1031 | xfs_da_state_t *state; | ||
| 1032 | xfs_da_state_blk_t *blk; | ||
| 1033 | xfs_dir_leafblock_t *leaf; | ||
| 1034 | xfs_dir_leaf_entry_t *entry; | ||
| 1035 | xfs_dir_leaf_name_t *namest; | ||
| 1036 | xfs_ino_t inum; | ||
| 1037 | int retval, error, i; | ||
| 1038 | xfs_dabuf_t *bp; | ||
| 1039 | |||
| 1040 | state = xfs_da_state_alloc(); | ||
| 1041 | state->args = args; | ||
| 1042 | state->mp = args->dp->i_mount; | ||
| 1043 | state->blocksize = state->mp->m_sb.sb_blocksize; | ||
| 1044 | state->node_ents = state->mp->m_dir_node_ents; | ||
| 1045 | inum = args->inumber; | ||
| 1046 | |||
| 1047 | /* | ||
| 1048 | * Search to see if name exists, | ||
| 1049 | * and get back a pointer to it. | ||
| 1050 | */ | ||
| 1051 | error = xfs_da_node_lookup_int(state, &retval); | ||
| 1052 | if (error) { | ||
| 1053 | retval = error; | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | if (retval == EEXIST) { | ||
| 1057 | blk = &state->path.blk[state->path.active - 1]; | ||
| 1058 | ASSERT(blk->magic == XFS_DIR_LEAF_MAGIC); | ||
| 1059 | bp = blk->bp; | ||
| 1060 | leaf = bp->data; | ||
| 1061 | entry = &leaf->entries[blk->index]; | ||
| 1062 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); | ||
| 1063 | /* XXX - replace assert ? */ | ||
| 1064 | XFS_DIR_SF_PUT_DIRINO(&inum, &namest->inumber); | ||
| 1065 | xfs_da_log_buf(args->trans, bp, | ||
| 1066 | XFS_DA_LOGRANGE(leaf, namest, sizeof(namest->inumber))); | ||
| 1067 | xfs_da_buf_done(bp); | ||
| 1068 | blk->bp = NULL; | ||
| 1069 | retval = 0; | ||
| 1070 | } else { | ||
| 1071 | i = state->path.active - 1; | ||
| 1072 | xfs_da_brelse(args->trans, state->path.blk[i].bp); | ||
| 1073 | state->path.blk[i].bp = NULL; | ||
| 1074 | } | ||
| 1075 | for (i = 0; i < state->path.active - 1; i++) { | ||
| 1076 | xfs_da_brelse(args->trans, state->path.blk[i].bp); | ||
| 1077 | state->path.blk[i].bp = NULL; | ||
| 1078 | } | ||
| 1079 | |||
| 1080 | xfs_da_state_free(state); | ||
| 1081 | return(retval); | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | #if defined(XFS_DIR_TRACE) | ||
| 1085 | /* | ||
| 1086 | * Add a trace buffer entry for an inode and a uio. | ||
| 1087 | */ | ||
| 1088 | void | ||
| 1089 | xfs_dir_trace_g_du(char *where, xfs_inode_t *dp, uio_t *uio) | ||
| 1090 | { | ||
| 1091 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DU, where, | ||
| 1092 | (void *)dp, (void *)dp->i_mount, | ||
| 1093 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
| 1094 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
| 1095 | (void *)(unsigned long)uio->uio_resid, | ||
| 1096 | NULL, NULL, NULL, NULL, NULL, NULL, NULL); | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | /* | ||
| 1100 | * Add a trace buffer entry for an inode and a uio. | ||
| 1101 | */ | ||
| 1102 | void | ||
| 1103 | xfs_dir_trace_g_dub(char *where, xfs_inode_t *dp, uio_t *uio, xfs_dablk_t bno) | ||
| 1104 | { | ||
| 1105 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUB, where, | ||
| 1106 | (void *)dp, (void *)dp->i_mount, | ||
| 1107 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
| 1108 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
| 1109 | (void *)(unsigned long)uio->uio_resid, | ||
| 1110 | (void *)(unsigned long)bno, | ||
| 1111 | NULL, NULL, NULL, NULL, NULL, NULL); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | /* | ||
| 1115 | * Add a trace buffer entry for an inode and a uio. | ||
| 1116 | */ | ||
| 1117 | void | ||
| 1118 | xfs_dir_trace_g_dun(char *where, xfs_inode_t *dp, uio_t *uio, | ||
| 1119 | xfs_da_intnode_t *node) | ||
| 1120 | { | ||
| 1121 | int last = be16_to_cpu(node->hdr.count) - 1; | ||
| 1122 | |||
| 1123 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUN, where, | ||
| 1124 | (void *)dp, (void *)dp->i_mount, | ||
| 1125 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
| 1126 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
| 1127 | (void *)(unsigned long)uio->uio_resid, | ||
| 1128 | (void *)(unsigned long)be32_to_cpu(node->hdr.info.forw), | ||
| 1129 | (void *)(unsigned long) | ||
| 1130 | be16_to_cpu(node->hdr.count), | ||
| 1131 | (void *)(unsigned long) | ||
| 1132 | be32_to_cpu(node->btree[0].hashval), | ||
| 1133 | (void *)(unsigned long) | ||
| 1134 | be32_to_cpu(node->btree[last].hashval), | ||
| 1135 | NULL, NULL, NULL); | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | /* | ||
| 1139 | * Add a trace buffer entry for an inode and a uio. | ||
| 1140 | */ | ||
| 1141 | void | ||
| 1142 | xfs_dir_trace_g_dul(char *where, xfs_inode_t *dp, uio_t *uio, | ||
| 1143 | xfs_dir_leafblock_t *leaf) | ||
| 1144 | { | ||
| 1145 | int last = be16_to_cpu(leaf->hdr.count) - 1; | ||
| 1146 | |||
| 1147 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUL, where, | ||
| 1148 | (void *)dp, (void *)dp->i_mount, | ||
| 1149 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
| 1150 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
| 1151 | (void *)(unsigned long)uio->uio_resid, | ||
| 1152 | (void *)(unsigned long)be32_to_cpu(leaf->hdr.info.forw), | ||
| 1153 | (void *)(unsigned long)be16_to_cpu(leaf->hdr.count), | ||
| 1154 | (void *)(unsigned long)be32_to_cpu(leaf->entries[0].hashval), | ||
| 1155 | (void *)(unsigned long)be32_to_cpu(leaf->entries[last].hashval), | ||
| 1156 | NULL, NULL, NULL); | ||
| 1157 | } | ||
| 1158 | |||
| 1159 | /* | ||
| 1160 | * Add a trace buffer entry for an inode and a uio. | ||
| 1161 | */ | ||
| 1162 | void | ||
| 1163 | xfs_dir_trace_g_due(char *where, xfs_inode_t *dp, uio_t *uio, | ||
| 1164 | xfs_dir_leaf_entry_t *entry) | ||
| 1165 | { | ||
| 1166 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUE, where, | ||
| 1167 | (void *)dp, (void *)dp->i_mount, | ||
| 1168 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
| 1169 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
| 1170 | (void *)(unsigned long)uio->uio_resid, | ||
| 1171 | (void *)(unsigned long)be32_to_cpu(entry->hashval), | ||
| 1172 | NULL, NULL, NULL, NULL, NULL, NULL); | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | /* | ||
| 1176 | * Add a trace buffer entry for an inode and a uio. | ||
| 1177 | */ | ||
| 1178 | void | ||
| 1179 | xfs_dir_trace_g_duc(char *where, xfs_inode_t *dp, uio_t *uio, xfs_off_t cookie) | ||
| 1180 | { | ||
| 1181 | xfs_dir_trace_enter(XFS_DIR_KTRACE_G_DUC, where, | ||
| 1182 | (void *)dp, (void *)dp->i_mount, | ||
| 1183 | (void *)((unsigned long)(uio->uio_offset >> 32)), | ||
| 1184 | (void *)((unsigned long)(uio->uio_offset & 0xFFFFFFFF)), | ||
| 1185 | (void *)(unsigned long)uio->uio_resid, | ||
| 1186 | (void *)((unsigned long)(cookie >> 32)), | ||
| 1187 | (void *)((unsigned long)(cookie & 0xFFFFFFFF)), | ||
| 1188 | NULL, NULL, NULL, NULL, NULL); | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | /* | ||
| 1192 | * Add a trace buffer entry for the arguments given to the routine, | ||
| 1193 | * generic form. | ||
| 1194 | */ | ||
| 1195 | void | ||
| 1196 | xfs_dir_trace_enter(int type, char *where, | ||
| 1197 | void * a0, void * a1, | ||
| 1198 | void * a2, void * a3, | ||
| 1199 | void * a4, void * a5, | ||
| 1200 | void * a6, void * a7, | ||
| 1201 | void * a8, void * a9, | ||
| 1202 | void * a10, void * a11) | ||
| 1203 | { | ||
| 1204 | ASSERT(xfs_dir_trace_buf); | ||
| 1205 | ktrace_enter(xfs_dir_trace_buf, (void *)(unsigned long)type, | ||
| 1206 | (void *)where, | ||
| 1207 | (void *)a0, (void *)a1, (void *)a2, | ||
| 1208 | (void *)a3, (void *)a4, (void *)a5, | ||
| 1209 | (void *)a6, (void *)a7, (void *)a8, | ||
| 1210 | (void *)a9, (void *)a10, (void *)a11, | ||
| 1211 | NULL, NULL); | ||
| 1212 | } | ||
| 1213 | #endif /* XFS_DIR_TRACE */ | ||
diff --git a/fs/xfs/xfs_dir.h b/fs/xfs/xfs_dir.h index 8cc8afb9f6c0..e69de29bb2d1 100644 --- a/fs/xfs/xfs_dir.h +++ b/fs/xfs/xfs_dir.h | |||
| @@ -1,142 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write the Free Software Foundation, | ||
| 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | #ifndef __XFS_DIR_H__ | ||
| 19 | #define __XFS_DIR_H__ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Large directories are structured around Btrees where all the data | ||
| 23 | * elements are in the leaf nodes. Filenames are hashed into an int, | ||
| 24 | * then that int is used as the index into the Btree. Since the hashval | ||
| 25 | * of a filename may not be unique, we may have duplicate keys. The | ||
| 26 | * internal links in the Btree are logical block offsets into the file. | ||
| 27 | * | ||
| 28 | * Small directories use a different format and are packed as tightly | ||
| 29 | * as possible so as to fit into the literal area of the inode. | ||
| 30 | */ | ||
| 31 | |||
| 32 | /*======================================================================== | ||
| 33 | * Function prototypes for the kernel. | ||
| 34 | *========================================================================*/ | ||
| 35 | |||
| 36 | struct uio; | ||
| 37 | struct xfs_bmap_free; | ||
| 38 | struct xfs_da_args; | ||
| 39 | struct xfs_dinode; | ||
| 40 | struct xfs_inode; | ||
| 41 | struct xfs_mount; | ||
| 42 | struct xfs_trans; | ||
| 43 | |||
| 44 | /* | ||
| 45 | * Directory function types. | ||
| 46 | * Put in structures (xfs_dirops_t) for v1 and v2 directories. | ||
| 47 | */ | ||
| 48 | typedef void (*xfs_dir_mount_t)(struct xfs_mount *mp); | ||
| 49 | typedef int (*xfs_dir_isempty_t)(struct xfs_inode *dp); | ||
| 50 | typedef int (*xfs_dir_init_t)(struct xfs_trans *tp, | ||
| 51 | struct xfs_inode *dp, | ||
| 52 | struct xfs_inode *pdp); | ||
| 53 | typedef int (*xfs_dir_createname_t)(struct xfs_trans *tp, | ||
| 54 | struct xfs_inode *dp, | ||
| 55 | char *name, | ||
| 56 | int namelen, | ||
| 57 | xfs_ino_t inum, | ||
| 58 | xfs_fsblock_t *first, | ||
| 59 | struct xfs_bmap_free *flist, | ||
| 60 | xfs_extlen_t total); | ||
| 61 | typedef int (*xfs_dir_lookup_t)(struct xfs_trans *tp, | ||
| 62 | struct xfs_inode *dp, | ||
| 63 | char *name, | ||
| 64 | int namelen, | ||
| 65 | xfs_ino_t *inum); | ||
| 66 | typedef int (*xfs_dir_removename_t)(struct xfs_trans *tp, | ||
| 67 | struct xfs_inode *dp, | ||
| 68 | char *name, | ||
| 69 | int namelen, | ||
| 70 | xfs_ino_t ino, | ||
| 71 | xfs_fsblock_t *first, | ||
| 72 | struct xfs_bmap_free *flist, | ||
| 73 | xfs_extlen_t total); | ||
| 74 | typedef int (*xfs_dir_getdents_t)(struct xfs_trans *tp, | ||
| 75 | struct xfs_inode *dp, | ||
| 76 | struct uio *uio, | ||
| 77 | int *eofp); | ||
| 78 | typedef int (*xfs_dir_replace_t)(struct xfs_trans *tp, | ||
| 79 | struct xfs_inode *dp, | ||
| 80 | char *name, | ||
| 81 | int namelen, | ||
| 82 | xfs_ino_t inum, | ||
| 83 | xfs_fsblock_t *first, | ||
| 84 | struct xfs_bmap_free *flist, | ||
| 85 | xfs_extlen_t total); | ||
| 86 | typedef int (*xfs_dir_canenter_t)(struct xfs_trans *tp, | ||
| 87 | struct xfs_inode *dp, | ||
| 88 | char *name, | ||
| 89 | int namelen); | ||
| 90 | typedef int (*xfs_dir_shortform_validate_ondisk_t)(struct xfs_mount *mp, | ||
| 91 | struct xfs_dinode *dip); | ||
| 92 | typedef int (*xfs_dir_shortform_to_single_t)(struct xfs_da_args *args); | ||
| 93 | |||
| 94 | typedef struct xfs_dirops { | ||
| 95 | xfs_dir_mount_t xd_mount; | ||
| 96 | xfs_dir_isempty_t xd_isempty; | ||
| 97 | xfs_dir_init_t xd_init; | ||
| 98 | xfs_dir_createname_t xd_createname; | ||
| 99 | xfs_dir_lookup_t xd_lookup; | ||
| 100 | xfs_dir_removename_t xd_removename; | ||
| 101 | xfs_dir_getdents_t xd_getdents; | ||
| 102 | xfs_dir_replace_t xd_replace; | ||
| 103 | xfs_dir_canenter_t xd_canenter; | ||
| 104 | xfs_dir_shortform_validate_ondisk_t xd_shortform_validate_ondisk; | ||
| 105 | xfs_dir_shortform_to_single_t xd_shortform_to_single; | ||
| 106 | } xfs_dirops_t; | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Overall external interface routines. | ||
| 110 | */ | ||
| 111 | void xfs_dir_startup(void); /* called exactly once */ | ||
| 112 | |||
| 113 | #define XFS_DIR_MOUNT(mp) \ | ||
| 114 | ((mp)->m_dirops.xd_mount(mp)) | ||
| 115 | #define XFS_DIR_ISEMPTY(mp,dp) \ | ||
| 116 | ((mp)->m_dirops.xd_isempty(dp)) | ||
| 117 | #define XFS_DIR_INIT(mp,tp,dp,pdp) \ | ||
| 118 | ((mp)->m_dirops.xd_init(tp,dp,pdp)) | ||
| 119 | #define XFS_DIR_CREATENAME(mp,tp,dp,name,namelen,inum,first,flist,total) \ | ||
| 120 | ((mp)->m_dirops.xd_createname(tp,dp,name,namelen,inum,first,flist,\ | ||
| 121 | total)) | ||
| 122 | #define XFS_DIR_LOOKUP(mp,tp,dp,name,namelen,inum) \ | ||
| 123 | ((mp)->m_dirops.xd_lookup(tp,dp,name,namelen,inum)) | ||
| 124 | #define XFS_DIR_REMOVENAME(mp,tp,dp,name,namelen,ino,first,flist,total) \ | ||
| 125 | ((mp)->m_dirops.xd_removename(tp,dp,name,namelen,ino,first,flist,total)) | ||
| 126 | #define XFS_DIR_GETDENTS(mp,tp,dp,uio,eofp) \ | ||
| 127 | ((mp)->m_dirops.xd_getdents(tp,dp,uio,eofp)) | ||
| 128 | #define XFS_DIR_REPLACE(mp,tp,dp,name,namelen,inum,first,flist,total) \ | ||
| 129 | ((mp)->m_dirops.xd_replace(tp,dp,name,namelen,inum,first,flist,total)) | ||
| 130 | #define XFS_DIR_CANENTER(mp,tp,dp,name,namelen) \ | ||
| 131 | ((mp)->m_dirops.xd_canenter(tp,dp,name,namelen)) | ||
| 132 | #define XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp,dip) \ | ||
| 133 | ((mp)->m_dirops.xd_shortform_validate_ondisk(mp,dip)) | ||
| 134 | #define XFS_DIR_SHORTFORM_TO_SINGLE(mp,args) \ | ||
| 135 | ((mp)->m_dirops.xd_shortform_to_single(args)) | ||
| 136 | |||
| 137 | #define XFS_DIR_IS_V1(mp) ((mp)->m_dirversion == 1) | ||
| 138 | #define XFS_DIR_IS_V2(mp) ((mp)->m_dirversion == 2) | ||
| 139 | extern xfs_dirops_t xfsv1_dirops; | ||
| 140 | extern xfs_dirops_t xfsv2_dirops; | ||
| 141 | |||
| 142 | #endif /* __XFS_DIR_H__ */ | ||
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 80238a2263fa..8edbe1adb95b 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
| @@ -24,21 +24,18 @@ | |||
| 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_da_btree.h" | 30 | #include "xfs_da_btree.h" |
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_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" |
| 38 | #include "xfs_inode.h" | 36 | #include "xfs_inode.h" |
| 39 | #include "xfs_inode_item.h" | 37 | #include "xfs_inode_item.h" |
| 40 | #include "xfs_bmap.h" | 38 | #include "xfs_bmap.h" |
| 41 | #include "xfs_dir_leaf.h" | ||
| 42 | #include "xfs_dir2_data.h" | 39 | #include "xfs_dir2_data.h" |
| 43 | #include "xfs_dir2_leaf.h" | 40 | #include "xfs_dir2_leaf.h" |
| 44 | #include "xfs_dir2_block.h" | 41 | #include "xfs_dir2_block.h" |
| @@ -46,69 +43,14 @@ | |||
| 46 | #include "xfs_dir2_trace.h" | 43 | #include "xfs_dir2_trace.h" |
| 47 | #include "xfs_error.h" | 44 | #include "xfs_error.h" |
| 48 | 45 | ||
| 49 | /* | ||
| 50 | * Declarations for interface routines. | ||
| 51 | */ | ||
| 52 | static void xfs_dir2_mount(xfs_mount_t *mp); | ||
| 53 | static int xfs_dir2_isempty(xfs_inode_t *dp); | ||
| 54 | static int xfs_dir2_init(xfs_trans_t *tp, xfs_inode_t *dp, | ||
| 55 | xfs_inode_t *pdp); | ||
| 56 | static int xfs_dir2_createname(xfs_trans_t *tp, xfs_inode_t *dp, | ||
| 57 | char *name, int namelen, xfs_ino_t inum, | ||
| 58 | xfs_fsblock_t *first, | ||
| 59 | xfs_bmap_free_t *flist, xfs_extlen_t total); | ||
| 60 | static int xfs_dir2_lookup(xfs_trans_t *tp, xfs_inode_t *dp, char *name, | ||
| 61 | int namelen, xfs_ino_t *inum); | ||
| 62 | static int xfs_dir2_removename(xfs_trans_t *tp, xfs_inode_t *dp, | ||
| 63 | char *name, int namelen, xfs_ino_t ino, | ||
| 64 | xfs_fsblock_t *first, | ||
| 65 | xfs_bmap_free_t *flist, xfs_extlen_t total); | ||
| 66 | static int xfs_dir2_getdents(xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio, | ||
| 67 | int *eofp); | ||
| 68 | static int xfs_dir2_replace(xfs_trans_t *tp, xfs_inode_t *dp, char *name, | ||
| 69 | int namelen, xfs_ino_t inum, | ||
| 70 | xfs_fsblock_t *first, xfs_bmap_free_t *flist, | ||
| 71 | xfs_extlen_t total); | ||
| 72 | static int xfs_dir2_canenter(xfs_trans_t *tp, xfs_inode_t *dp, char *name, | ||
| 73 | int namelen); | ||
| 74 | static int xfs_dir2_shortform_validate_ondisk(xfs_mount_t *mp, | ||
| 75 | xfs_dinode_t *dip); | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Utility routine declarations. | ||
| 79 | */ | ||
| 80 | static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); | 46 | static int xfs_dir2_put_dirent64_direct(xfs_dir2_put_args_t *pa); |
| 81 | static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); | 47 | static int xfs_dir2_put_dirent64_uio(xfs_dir2_put_args_t *pa); |
| 82 | 48 | ||
| 83 | /* | 49 | void |
| 84 | * Directory operations vector. | 50 | xfs_dir_mount( |
| 85 | */ | 51 | xfs_mount_t *mp) |
| 86 | xfs_dirops_t xfsv2_dirops = { | ||
| 87 | .xd_mount = xfs_dir2_mount, | ||
| 88 | .xd_isempty = xfs_dir2_isempty, | ||
| 89 | .xd_init = xfs_dir2_init, | ||
| 90 | .xd_createname = xfs_dir2_createname, | ||
| 91 | .xd_lookup = xfs_dir2_lookup, | ||
| 92 | .xd_removename = xfs_dir2_removename, | ||
| 93 | .xd_getdents = xfs_dir2_getdents, | ||
| 94 | .xd_replace = xfs_dir2_replace, | ||
| 95 | .xd_canenter = xfs_dir2_canenter, | ||
| 96 | .xd_shortform_validate_ondisk = xfs_dir2_shortform_validate_ondisk, | ||
| 97 | .xd_shortform_to_single = xfs_dir2_sf_to_block, | ||
| 98 | }; | ||
| 99 | |||
| 100 | /* | ||
| 101 | * Interface routines. | ||
| 102 | */ | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Initialize directory-related fields in the mount structure. | ||
| 106 | */ | ||
| 107 | static void | ||
| 108 | xfs_dir2_mount( | ||
| 109 | xfs_mount_t *mp) /* filesystem mount point */ | ||
| 110 | { | 52 | { |
| 111 | mp->m_dirversion = 2; | 53 | ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb)); |
| 112 | ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= | 54 | ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <= |
| 113 | XFS_MAX_BLOCKSIZE); | 55 | XFS_MAX_BLOCKSIZE); |
| 114 | mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); | 56 | mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); |
| @@ -128,19 +70,15 @@ xfs_dir2_mount( | |||
| 128 | /* | 70 | /* |
| 129 | * Return 1 if directory contains only "." and "..". | 71 | * Return 1 if directory contains only "." and "..". |
| 130 | */ | 72 | */ |
| 131 | static int /* return code */ | 73 | int |
| 132 | xfs_dir2_isempty( | 74 | xfs_dir_isempty( |
| 133 | xfs_inode_t *dp) /* incore inode structure */ | 75 | xfs_inode_t *dp) |
| 134 | { | 76 | { |
| 135 | xfs_dir2_sf_t *sfp; /* shortform directory structure */ | 77 | xfs_dir2_sf_t *sfp; |
| 136 | 78 | ||
| 137 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 79 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
| 138 | /* | 80 | if (dp->i_d.di_size == 0) /* might happen during shutdown. */ |
| 139 | * Might happen during shutdown. | ||
| 140 | */ | ||
| 141 | if (dp->i_d.di_size == 0) { | ||
| 142 | return 1; | 81 | return 1; |
| 143 | } | ||
| 144 | if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) | 82 | if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) |
| 145 | return 0; | 83 | return 0; |
| 146 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 84 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
| @@ -148,53 +86,83 @@ xfs_dir2_isempty( | |||
| 148 | } | 86 | } |
| 149 | 87 | ||
| 150 | /* | 88 | /* |
| 89 | * Validate a given inode number. | ||
| 90 | */ | ||
| 91 | int | ||
| 92 | xfs_dir_ino_validate( | ||
| 93 | xfs_mount_t *mp, | ||
| 94 | xfs_ino_t ino) | ||
| 95 | { | ||
| 96 | xfs_agblock_t agblkno; | ||
| 97 | xfs_agino_t agino; | ||
| 98 | xfs_agnumber_t agno; | ||
| 99 | int ino_ok; | ||
| 100 | int ioff; | ||
| 101 | |||
| 102 | agno = XFS_INO_TO_AGNO(mp, ino); | ||
| 103 | agblkno = XFS_INO_TO_AGBNO(mp, ino); | ||
| 104 | ioff = XFS_INO_TO_OFFSET(mp, ino); | ||
| 105 | agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff); | ||
| 106 | ino_ok = | ||
| 107 | agno < mp->m_sb.sb_agcount && | ||
| 108 | agblkno < mp->m_sb.sb_agblocks && | ||
| 109 | agblkno != 0 && | ||
| 110 | ioff < (1 << mp->m_sb.sb_inopblog) && | ||
| 111 | XFS_AGINO_TO_INO(mp, agno, agino) == ino; | ||
| 112 | if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, | ||
| 113 | XFS_RANDOM_DIR_INO_VALIDATE))) { | ||
| 114 | xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", | ||
| 115 | (unsigned long long) ino); | ||
| 116 | XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); | ||
| 117 | return XFS_ERROR(EFSCORRUPTED); | ||
| 118 | } | ||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | |||
| 122 | /* | ||
| 151 | * Initialize a directory with its "." and ".." entries. | 123 | * Initialize a directory with its "." and ".." entries. |
| 152 | */ | 124 | */ |
| 153 | static int /* error */ | 125 | int |
| 154 | xfs_dir2_init( | 126 | xfs_dir_init( |
| 155 | xfs_trans_t *tp, /* transaction pointer */ | 127 | xfs_trans_t *tp, |
| 156 | xfs_inode_t *dp, /* incore directory inode */ | 128 | xfs_inode_t *dp, |
| 157 | xfs_inode_t *pdp) /* incore parent directory inode */ | 129 | xfs_inode_t *pdp) |
| 158 | { | 130 | { |
| 159 | xfs_da_args_t args; /* operation arguments */ | 131 | xfs_da_args_t args; |
| 160 | int error; /* error return value */ | 132 | int error; |
| 161 | 133 | ||
| 162 | memset((char *)&args, 0, sizeof(args)); | 134 | memset((char *)&args, 0, sizeof(args)); |
| 163 | args.dp = dp; | 135 | args.dp = dp; |
| 164 | args.trans = tp; | 136 | args.trans = tp; |
| 165 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 137 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
| 166 | if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) { | 138 | if ((error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino))) |
| 167 | return error; | 139 | return error; |
| 168 | } | ||
| 169 | return xfs_dir2_sf_create(&args, pdp->i_ino); | 140 | return xfs_dir2_sf_create(&args, pdp->i_ino); |
| 170 | } | 141 | } |
| 171 | 142 | ||
| 172 | /* | 143 | /* |
| 173 | Enter a name in a directory. | 144 | Enter a name in a directory. |
| 174 | */ | 145 | */ |
| 175 | static int /* error */ | 146 | int |
| 176 | xfs_dir2_createname( | 147 | xfs_dir_createname( |
| 177 | xfs_trans_t *tp, /* transaction pointer */ | 148 | xfs_trans_t *tp, |
| 178 | xfs_inode_t *dp, /* incore directory inode */ | 149 | xfs_inode_t *dp, |
| 179 | char *name, /* new entry name */ | 150 | char *name, |
| 180 | int namelen, /* new entry name length */ | 151 | int namelen, |
| 181 | xfs_ino_t inum, /* new entry inode number */ | 152 | xfs_ino_t inum, /* new entry inode number */ |
| 182 | xfs_fsblock_t *first, /* bmap's firstblock */ | 153 | xfs_fsblock_t *first, /* bmap's firstblock */ |
| 183 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ | 154 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ |
| 184 | xfs_extlen_t total) /* bmap's total block count */ | 155 | xfs_extlen_t total) /* bmap's total block count */ |
| 185 | { | 156 | { |
| 186 | xfs_da_args_t args; /* operation arguments */ | 157 | xfs_da_args_t args; |
| 187 | int rval; /* return value */ | 158 | int rval; |
| 188 | int v; /* type-checking value */ | 159 | int v; /* type-checking value */ |
| 189 | 160 | ||
| 190 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 161 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
| 191 | if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { | 162 | if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) |
| 192 | return rval; | 163 | return rval; |
| 193 | } | ||
| 194 | XFS_STATS_INC(xs_dir_create); | 164 | XFS_STATS_INC(xs_dir_create); |
| 195 | /* | 165 | |
| 196 | * Fill in the arg structure for this request. | ||
| 197 | */ | ||
| 198 | args.name = name; | 166 | args.name = name; |
| 199 | args.namelen = namelen; | 167 | args.namelen = namelen; |
| 200 | args.hashval = xfs_da_hashname(name, namelen); | 168 | args.hashval = xfs_da_hashname(name, namelen); |
| @@ -207,18 +175,16 @@ xfs_dir2_createname( | |||
| 207 | args.trans = tp; | 175 | args.trans = tp; |
| 208 | args.justcheck = 0; | 176 | args.justcheck = 0; |
| 209 | args.addname = args.oknoent = 1; | 177 | args.addname = args.oknoent = 1; |
| 210 | /* | 178 | |
| 211 | * Decide on what work routines to call based on the inode size. | ||
| 212 | */ | ||
| 213 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 179 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
| 214 | rval = xfs_dir2_sf_addname(&args); | 180 | rval = xfs_dir2_sf_addname(&args); |
| 215 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 181 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
| 216 | return rval; | 182 | return rval; |
| 217 | } else if (v) | 183 | else if (v) |
| 218 | rval = xfs_dir2_block_addname(&args); | 184 | rval = xfs_dir2_block_addname(&args); |
| 219 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 185 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
| 220 | return rval; | 186 | return rval; |
| 221 | } else if (v) | 187 | else if (v) |
| 222 | rval = xfs_dir2_leaf_addname(&args); | 188 | rval = xfs_dir2_leaf_addname(&args); |
| 223 | else | 189 | else |
| 224 | rval = xfs_dir2_node_addname(&args); | 190 | rval = xfs_dir2_node_addname(&args); |
| @@ -228,24 +194,21 @@ xfs_dir2_createname( | |||
| 228 | /* | 194 | /* |
| 229 | * Lookup a name in a directory, give back the inode number. | 195 | * Lookup a name in a directory, give back the inode number. |
| 230 | */ | 196 | */ |
| 231 | static int /* error */ | 197 | int |
| 232 | xfs_dir2_lookup( | 198 | xfs_dir_lookup( |
| 233 | xfs_trans_t *tp, /* transaction pointer */ | 199 | xfs_trans_t *tp, |
| 234 | xfs_inode_t *dp, /* incore directory inode */ | 200 | xfs_inode_t *dp, |
| 235 | char *name, /* lookup name */ | 201 | char *name, |
| 236 | int namelen, /* lookup name length */ | 202 | int namelen, |
| 237 | xfs_ino_t *inum) /* out: inode number */ | 203 | xfs_ino_t *inum) /* out: inode number */ |
| 238 | { | 204 | { |
| 239 | xfs_da_args_t args; /* operation arguments */ | 205 | xfs_da_args_t args; |
| 240 | int rval; /* return value */ | 206 | int rval; |
| 241 | int v; /* type-checking value */ | 207 | int v; /* type-checking value */ |
| 242 | 208 | ||
| 243 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 209 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
| 244 | XFS_STATS_INC(xs_dir_lookup); | 210 | XFS_STATS_INC(xs_dir_lookup); |
| 245 | 211 | ||
| 246 | /* | ||
| 247 | * Fill in the arg structure for this request. | ||
| 248 | */ | ||
| 249 | args.name = name; | 212 | args.name = name; |
| 250 | args.namelen = namelen; | 213 | args.namelen = namelen; |
| 251 | args.hashval = xfs_da_hashname(name, namelen); | 214 | args.hashval = xfs_da_hashname(name, namelen); |
| @@ -258,18 +221,16 @@ xfs_dir2_lookup( | |||
| 258 | args.trans = tp; | 221 | args.trans = tp; |
| 259 | args.justcheck = args.addname = 0; | 222 | args.justcheck = args.addname = 0; |
| 260 | args.oknoent = 1; | 223 | args.oknoent = 1; |
| 261 | /* | 224 | |
| 262 | * Decide on what work routines to call based on the inode size. | ||
| 263 | */ | ||
| 264 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 225 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
| 265 | rval = xfs_dir2_sf_lookup(&args); | 226 | rval = xfs_dir2_sf_lookup(&args); |
| 266 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 227 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
| 267 | return rval; | 228 | return rval; |
| 268 | } else if (v) | 229 | else if (v) |
| 269 | rval = xfs_dir2_block_lookup(&args); | 230 | rval = xfs_dir2_block_lookup(&args); |
| 270 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 231 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
| 271 | return rval; | 232 | return rval; |
| 272 | } else if (v) | 233 | else if (v) |
| 273 | rval = xfs_dir2_leaf_lookup(&args); | 234 | rval = xfs_dir2_leaf_lookup(&args); |
| 274 | else | 235 | else |
| 275 | rval = xfs_dir2_node_lookup(&args); | 236 | rval = xfs_dir2_node_lookup(&args); |
| @@ -283,26 +244,24 @@ xfs_dir2_lookup( | |||
| 283 | /* | 244 | /* |
| 284 | * Remove an entry from a directory. | 245 | * Remove an entry from a directory. |
| 285 | */ | 246 | */ |
| 286 | static int /* error */ | 247 | int |
| 287 | xfs_dir2_removename( | 248 | xfs_dir_removename( |
| 288 | xfs_trans_t *tp, /* transaction pointer */ | 249 | xfs_trans_t *tp, |
| 289 | xfs_inode_t *dp, /* incore directory inode */ | 250 | xfs_inode_t *dp, |
| 290 | char *name, /* name of entry to remove */ | 251 | char *name, |
| 291 | int namelen, /* name length of entry to remove */ | 252 | int namelen, |
| 292 | xfs_ino_t ino, /* inode number of entry to remove */ | 253 | xfs_ino_t ino, |
| 293 | xfs_fsblock_t *first, /* bmap's firstblock */ | 254 | xfs_fsblock_t *first, /* bmap's firstblock */ |
| 294 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ | 255 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ |
| 295 | xfs_extlen_t total) /* bmap's total block count */ | 256 | xfs_extlen_t total) /* bmap's total block count */ |
| 296 | { | 257 | { |
| 297 | xfs_da_args_t args; /* operation arguments */ | 258 | xfs_da_args_t args; |
| 298 | int rval; /* return value */ | 259 | int rval; |
| 299 | int v; /* type-checking value */ | 260 | int v; /* type-checking value */ |
| 300 | 261 | ||
| 301 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 262 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
| 302 | XFS_STATS_INC(xs_dir_remove); | 263 | XFS_STATS_INC(xs_dir_remove); |
| 303 | /* | 264 | |
| 304 | * Fill in the arg structure for this request. | ||
| 305 | */ | ||
| 306 | args.name = name; | 265 | args.name = name; |
| 307 | args.namelen = namelen; | 266 | args.namelen = namelen; |
| 308 | args.hashval = xfs_da_hashname(name, namelen); | 267 | args.hashval = xfs_da_hashname(name, namelen); |
| @@ -314,18 +273,16 @@ xfs_dir2_removename( | |||
| 314 | args.whichfork = XFS_DATA_FORK; | 273 | args.whichfork = XFS_DATA_FORK; |
| 315 | args.trans = tp; | 274 | args.trans = tp; |
| 316 | args.justcheck = args.addname = args.oknoent = 0; | 275 | args.justcheck = args.addname = args.oknoent = 0; |
| 317 | /* | 276 | |
| 318 | * Decide on what work routines to call based on the inode size. | ||
| 319 | */ | ||
| 320 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 277 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
| 321 | rval = xfs_dir2_sf_removename(&args); | 278 | rval = xfs_dir2_sf_removename(&args); |
| 322 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 279 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
| 323 | return rval; | 280 | return rval; |
| 324 | } else if (v) | 281 | else if (v) |
| 325 | rval = xfs_dir2_block_removename(&args); | 282 | rval = xfs_dir2_block_removename(&args); |
| 326 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 283 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
| 327 | return rval; | 284 | return rval; |
| 328 | } else if (v) | 285 | else if (v) |
| 329 | rval = xfs_dir2_leaf_removename(&args); | 286 | rval = xfs_dir2_leaf_removename(&args); |
| 330 | else | 287 | else |
| 331 | rval = xfs_dir2_node_removename(&args); | 288 | rval = xfs_dir2_node_removename(&args); |
| @@ -335,10 +292,10 @@ xfs_dir2_removename( | |||
| 335 | /* | 292 | /* |
| 336 | * Read a directory. | 293 | * Read a directory. |
| 337 | */ | 294 | */ |
| 338 | static int /* error */ | 295 | int |
| 339 | xfs_dir2_getdents( | 296 | xfs_dir_getdents( |
| 340 | xfs_trans_t *tp, /* transaction pointer */ | 297 | xfs_trans_t *tp, |
| 341 | xfs_inode_t *dp, /* incore directory inode */ | 298 | xfs_inode_t *dp, |
| 342 | uio_t *uio, /* caller's buffer control */ | 299 | uio_t *uio, /* caller's buffer control */ |
| 343 | int *eofp) /* out: eof reached */ | 300 | int *eofp) /* out: eof reached */ |
| 344 | { | 301 | { |
| @@ -367,14 +324,11 @@ xfs_dir2_getdents( | |||
| 367 | } | 324 | } |
| 368 | 325 | ||
| 369 | *eofp = 0; | 326 | *eofp = 0; |
| 370 | /* | ||
| 371 | * Decide on what work routines to call based on the inode size. | ||
| 372 | */ | ||
| 373 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 327 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
| 374 | rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); | 328 | rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); |
| 375 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 329 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
| 376 | ; | 330 | ; |
| 377 | } else if (v) | 331 | else if (v) |
| 378 | rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); | 332 | rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); |
| 379 | else | 333 | else |
| 380 | rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); | 334 | rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); |
| @@ -386,29 +340,26 @@ xfs_dir2_getdents( | |||
| 386 | /* | 340 | /* |
| 387 | * Replace the inode number of a directory entry. | 341 | * Replace the inode number of a directory entry. |
| 388 | */ | 342 | */ |
| 389 | static int /* error */ | 343 | int |
| 390 | xfs_dir2_replace( | 344 | xfs_dir_replace( |
| 391 | xfs_trans_t *tp, /* transaction pointer */ | 345 | xfs_trans_t *tp, |
| 392 | xfs_inode_t *dp, /* incore directory inode */ | 346 | xfs_inode_t *dp, |
| 393 | char *name, /* name of entry to replace */ | 347 | char *name, /* name of entry to replace */ |
| 394 | int namelen, /* name length of entry to replace */ | 348 | int namelen, |
| 395 | xfs_ino_t inum, /* new inode number */ | 349 | xfs_ino_t inum, /* new inode number */ |
| 396 | xfs_fsblock_t *first, /* bmap's firstblock */ | 350 | xfs_fsblock_t *first, /* bmap's firstblock */ |
| 397 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ | 351 | xfs_bmap_free_t *flist, /* bmap's freeblock list */ |
| 398 | xfs_extlen_t total) /* bmap's total block count */ | 352 | xfs_extlen_t total) /* bmap's total block count */ |
| 399 | { | 353 | { |
| 400 | xfs_da_args_t args; /* operation arguments */ | 354 | xfs_da_args_t args; |
| 401 | int rval; /* return value */ | 355 | int rval; |
| 402 | int v; /* type-checking value */ | 356 | int v; /* type-checking value */ |
| 403 | 357 | ||
| 404 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 358 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
| 405 | 359 | ||
| 406 | if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) { | 360 | if ((rval = xfs_dir_ino_validate(tp->t_mountp, inum))) |
| 407 | return rval; | 361 | return rval; |
| 408 | } | 362 | |
| 409 | /* | ||
| 410 | * Fill in the arg structure for this request. | ||
| 411 | */ | ||
| 412 | args.name = name; | 363 | args.name = name; |
| 413 | args.namelen = namelen; | 364 | args.namelen = namelen; |
| 414 | args.hashval = xfs_da_hashname(name, namelen); | 365 | args.hashval = xfs_da_hashname(name, namelen); |
| @@ -420,18 +371,16 @@ xfs_dir2_replace( | |||
| 420 | args.whichfork = XFS_DATA_FORK; | 371 | args.whichfork = XFS_DATA_FORK; |
| 421 | args.trans = tp; | 372 | args.trans = tp; |
| 422 | args.justcheck = args.addname = args.oknoent = 0; | 373 | args.justcheck = args.addname = args.oknoent = 0; |
| 423 | /* | 374 | |
| 424 | * Decide on what work routines to call based on the inode size. | ||
| 425 | */ | ||
| 426 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 375 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
| 427 | rval = xfs_dir2_sf_replace(&args); | 376 | rval = xfs_dir2_sf_replace(&args); |
| 428 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 377 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
| 429 | return rval; | 378 | return rval; |
| 430 | } else if (v) | 379 | else if (v) |
| 431 | rval = xfs_dir2_block_replace(&args); | 380 | rval = xfs_dir2_block_replace(&args); |
| 432 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 381 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
| 433 | return rval; | 382 | return rval; |
| 434 | } else if (v) | 383 | else if (v) |
| 435 | rval = xfs_dir2_leaf_replace(&args); | 384 | rval = xfs_dir2_leaf_replace(&args); |
| 436 | else | 385 | else |
| 437 | rval = xfs_dir2_node_replace(&args); | 386 | rval = xfs_dir2_node_replace(&args); |
| @@ -441,21 +390,19 @@ xfs_dir2_replace( | |||
| 441 | /* | 390 | /* |
| 442 | * See if this entry can be added to the directory without allocating space. | 391 | * See if this entry can be added to the directory without allocating space. |
| 443 | */ | 392 | */ |
| 444 | static int /* error */ | 393 | int |
| 445 | xfs_dir2_canenter( | 394 | xfs_dir_canenter( |
| 446 | xfs_trans_t *tp, /* transaction pointer */ | 395 | xfs_trans_t *tp, |
| 447 | xfs_inode_t *dp, /* incore directory inode */ | 396 | xfs_inode_t *dp, |
| 448 | char *name, /* name of entry to add */ | 397 | char *name, /* name of entry to add */ |
| 449 | int namelen) /* name length of entry to add */ | 398 | int namelen) |
| 450 | { | 399 | { |
| 451 | xfs_da_args_t args; /* operation arguments */ | 400 | xfs_da_args_t args; |
| 452 | int rval; /* return value */ | 401 | int rval; |
| 453 | int v; /* type-checking value */ | 402 | int v; /* type-checking value */ |
| 454 | 403 | ||
| 455 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); | 404 | ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); |
| 456 | /* | 405 | |
| 457 | * Fill in the arg structure for this request. | ||
| 458 | */ | ||
| 459 | args.name = name; | 406 | args.name = name; |
| 460 | args.namelen = namelen; | 407 | args.namelen = namelen; |
| 461 | args.hashval = xfs_da_hashname(name, namelen); | 408 | args.hashval = xfs_da_hashname(name, namelen); |
| @@ -467,18 +414,16 @@ xfs_dir2_canenter( | |||
| 467 | args.whichfork = XFS_DATA_FORK; | 414 | args.whichfork = XFS_DATA_FORK; |
| 468 | args.trans = tp; | 415 | args.trans = tp; |
| 469 | args.justcheck = args.addname = args.oknoent = 1; | 416 | args.justcheck = args.addname = args.oknoent = 1; |
| 470 | /* | 417 | |
| 471 | * Decide on what work routines to call based on the inode size. | ||
| 472 | */ | ||
| 473 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) | 418 | if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) |
| 474 | rval = xfs_dir2_sf_addname(&args); | 419 | rval = xfs_dir2_sf_addname(&args); |
| 475 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) { | 420 | else if ((rval = xfs_dir2_isblock(tp, dp, &v))) |
| 476 | return rval; | 421 | return rval; |
| 477 | } else if (v) | 422 | else if (v) |
| 478 | rval = xfs_dir2_block_addname(&args); | 423 | rval = xfs_dir2_block_addname(&args); |
| 479 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) { | 424 | else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) |
| 480 | return rval; | 425 | return rval; |
| 481 | } else if (v) | 426 | else if (v) |
| 482 | rval = xfs_dir2_leaf_addname(&args); | 427 | rval = xfs_dir2_leaf_addname(&args); |
| 483 | else | 428 | else |
| 484 | rval = xfs_dir2_node_addname(&args); | 429 | rval = xfs_dir2_node_addname(&args); |
| @@ -486,19 +431,6 @@ xfs_dir2_canenter( | |||
| 486 | } | 431 | } |
| 487 | 432 | ||
| 488 | /* | 433 | /* |
| 489 | * Dummy routine for shortform inode validation. | ||
| 490 | * Can't really do this. | ||
| 491 | */ | ||
| 492 | /* ARGSUSED */ | ||
| 493 | static int /* error */ | ||
| 494 | xfs_dir2_shortform_validate_ondisk( | ||
| 495 | xfs_mount_t *mp, /* filesystem mount point */ | ||
| 496 | xfs_dinode_t *dip) /* ondisk inode */ | ||
| 497 | { | ||
| 498 | return 0; | ||
| 499 | } | ||
| 500 | |||
| 501 | /* | ||
| 502 | * Utility routines. | 434 | * Utility routines. |
| 503 | */ | 435 | */ |
| 504 | 436 | ||
| @@ -507,24 +439,24 @@ xfs_dir2_shortform_validate_ondisk( | |||
| 507 | * This routine is for data and free blocks, not leaf/node blocks | 439 | * This routine is for data and free blocks, not leaf/node blocks |
| 508 | * which are handled by xfs_da_grow_inode. | 440 | * which are handled by xfs_da_grow_inode. |
| 509 | */ | 441 | */ |
| 510 | int /* error */ | 442 | int |
| 511 | xfs_dir2_grow_inode( | 443 | xfs_dir2_grow_inode( |
| 512 | xfs_da_args_t *args, /* operation arguments */ | 444 | xfs_da_args_t *args, |
| 513 | int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ | 445 | int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */ |
| 514 | xfs_dir2_db_t *dbp) /* out: block number added */ | 446 | xfs_dir2_db_t *dbp) /* out: block number added */ |
| 515 | { | 447 | { |
| 516 | xfs_fileoff_t bno; /* directory offset of new block */ | 448 | xfs_fileoff_t bno; /* directory offset of new block */ |
| 517 | int count; /* count of filesystem blocks */ | 449 | int count; /* count of filesystem blocks */ |
| 518 | xfs_inode_t *dp; /* incore directory inode */ | 450 | xfs_inode_t *dp; /* incore directory inode */ |
| 519 | int error; /* error return value */ | 451 | int error; |
| 520 | int got; /* blocks actually mapped */ | 452 | int got; /* blocks actually mapped */ |
| 521 | int i; /* temp mapping index */ | 453 | int i; |
| 522 | xfs_bmbt_irec_t map; /* single structure for bmap */ | 454 | xfs_bmbt_irec_t map; /* single structure for bmap */ |
| 523 | int mapi; /* mapping index */ | 455 | int mapi; /* mapping index */ |
| 524 | xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ | 456 | xfs_bmbt_irec_t *mapp; /* bmap mapping structure(s) */ |
| 525 | xfs_mount_t *mp; /* filesystem mount point */ | 457 | xfs_mount_t *mp; |
| 526 | int nmap; /* number of bmap entries */ | 458 | int nmap; /* number of bmap entries */ |
| 527 | xfs_trans_t *tp; /* transaction pointer */ | 459 | xfs_trans_t *tp; |
| 528 | 460 | ||
| 529 | xfs_dir2_trace_args_s("grow_inode", args, space); | 461 | xfs_dir2_trace_args_s("grow_inode", args, space); |
| 530 | dp = args->dp; | 462 | dp = args->dp; |
| @@ -538,9 +470,8 @@ xfs_dir2_grow_inode( | |||
| 538 | /* | 470 | /* |
| 539 | * Find the first hole for our block. | 471 | * Find the first hole for our block. |
| 540 | */ | 472 | */ |
| 541 | if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) { | 473 | if ((error = xfs_bmap_first_unused(tp, dp, count, &bno, XFS_DATA_FORK))) |
| 542 | return error; | 474 | return error; |
| 543 | } | ||
| 544 | nmap = 1; | 475 | nmap = 1; |
| 545 | ASSERT(args->firstblock != NULL); | 476 | ASSERT(args->firstblock != NULL); |
| 546 | /* | 477 | /* |
| @@ -549,13 +480,9 @@ xfs_dir2_grow_inode( | |||
| 549 | if ((error = xfs_bmapi(tp, dp, bno, count, | 480 | if ((error = xfs_bmapi(tp, dp, bno, count, |
| 550 | XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, | 481 | XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, |
| 551 | args->firstblock, args->total, &map, &nmap, | 482 | args->firstblock, args->total, &map, &nmap, |
| 552 | args->flist, NULL))) { | 483 | args->flist, NULL))) |
| 553 | return error; | 484 | return error; |
| 554 | } | ||
| 555 | ASSERT(nmap <= 1); | 485 | ASSERT(nmap <= 1); |
| 556 | /* | ||
| 557 | * Got it in 1. | ||
| 558 | */ | ||
| 559 | if (nmap == 1) { | 486 | if (nmap == 1) { |
| 560 | mapp = ↦ | 487 | mapp = ↦ |
| 561 | mapi = 1; | 488 | mapi = 1; |
| @@ -646,20 +573,19 @@ xfs_dir2_grow_inode( | |||
| 646 | /* | 573 | /* |
| 647 | * See if the directory is a single-block form directory. | 574 | * See if the directory is a single-block form directory. |
| 648 | */ | 575 | */ |
| 649 | int /* error */ | 576 | int |
| 650 | xfs_dir2_isblock( | 577 | xfs_dir2_isblock( |
| 651 | xfs_trans_t *tp, /* transaction pointer */ | 578 | xfs_trans_t *tp, |
| 652 | xfs_inode_t *dp, /* incore directory inode */ | 579 | xfs_inode_t *dp, |
| 653 | int *vp) /* out: 1 is block, 0 is not block */ | 580 | int *vp) /* out: 1 is block, 0 is not block */ |
| 654 | { | 581 | { |
| 655 | xfs_fileoff_t last; /* last file offset */ | 582 | xfs_fileoff_t last; /* last file offset */ |
| 656 | xfs_mount_t *mp; /* filesystem mount point */ | 583 | xfs_mount_t *mp; |
| 657 | int rval; /* return value */ | 584 | int rval; |
| 658 | 585 | ||
| 659 | mp = dp->i_mount; | 586 | mp = dp->i_mount; |
| 660 | if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { | 587 | if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) |
| 661 | return rval; | 588 | return rval; |
| 662 | } | ||
| 663 | rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; | 589 | rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; |
| 664 | ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); | 590 | ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); |
| 665 | *vp = rval; | 591 | *vp = rval; |
| @@ -669,20 +595,19 @@ xfs_dir2_isblock( | |||
| 669 | /* | 595 | /* |
| 670 | * See if the directory is a single-leaf form directory. | 596 | * See if the directory is a single-leaf form directory. |
| 671 | */ | 597 | */ |
| 672 | int /* error */ | 598 | int |
| 673 | xfs_dir2_isleaf( | 599 | xfs_dir2_isleaf( |
| 674 | xfs_trans_t *tp, /* transaction pointer */ | 600 | xfs_trans_t *tp, |
| 675 | xfs_inode_t *dp, /* incore directory inode */ | 601 | xfs_inode_t *dp, |
| 676 | int *vp) /* out: 1 is leaf, 0 is not leaf */ | 602 | int *vp) /* out: 1 is leaf, 0 is not leaf */ |
| 677 | { | 603 | { |
| 678 | xfs_fileoff_t last; /* last file offset */ | 604 | xfs_fileoff_t last; /* last file offset */ |
| 679 | xfs_mount_t *mp; /* filesystem mount point */ | 605 | xfs_mount_t *mp; |
| 680 | int rval; /* return value */ | 606 | int rval; |
| 681 | 607 | ||
| 682 | mp = dp->i_mount; | 608 | mp = dp->i_mount; |
| 683 | if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) { | 609 | if ((rval = xfs_bmap_last_offset(tp, dp, &last, XFS_DATA_FORK))) |
| 684 | return rval; | 610 | return rval; |
| 685 | } | ||
| 686 | *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); | 611 | *vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); |
| 687 | return 0; | 612 | return 0; |
| 688 | } | 613 | } |
| @@ -690,9 +615,9 @@ xfs_dir2_isleaf( | |||
| 690 | /* | 615 | /* |
| 691 | * Getdents put routine for 64-bit ABI, direct form. | 616 | * Getdents put routine for 64-bit ABI, direct form. |
| 692 | */ | 617 | */ |
| 693 | static int /* error */ | 618 | static int |
| 694 | xfs_dir2_put_dirent64_direct( | 619 | xfs_dir2_put_dirent64_direct( |
| 695 | xfs_dir2_put_args_t *pa) /* argument bundle */ | 620 | xfs_dir2_put_args_t *pa) |
| 696 | { | 621 | { |
| 697 | xfs_dirent_t *idbp; /* dirent pointer */ | 622 | xfs_dirent_t *idbp; /* dirent pointer */ |
| 698 | iovec_t *iovp; /* io vector */ | 623 | iovec_t *iovp; /* io vector */ |
| @@ -727,9 +652,9 @@ xfs_dir2_put_dirent64_direct( | |||
| 727 | /* | 652 | /* |
| 728 | * Getdents put routine for 64-bit ABI, uio form. | 653 | * Getdents put routine for 64-bit ABI, uio form. |
| 729 | */ | 654 | */ |
| 730 | static int /* error */ | 655 | static int |
| 731 | xfs_dir2_put_dirent64_uio( | 656 | xfs_dir2_put_dirent64_uio( |
| 732 | xfs_dir2_put_args_t *pa) /* argument bundle */ | 657 | xfs_dir2_put_args_t *pa) |
| 733 | { | 658 | { |
| 734 | xfs_dirent_t *idbp; /* dirent pointer */ | 659 | xfs_dirent_t *idbp; /* dirent pointer */ |
| 735 | int namelen; /* entry name length */ | 660 | int namelen; /* entry name length */ |
| @@ -765,17 +690,17 @@ xfs_dir2_put_dirent64_uio( | |||
| 765 | */ | 690 | */ |
| 766 | int | 691 | int |
| 767 | xfs_dir2_shrink_inode( | 692 | xfs_dir2_shrink_inode( |
| 768 | xfs_da_args_t *args, /* operation arguments */ | 693 | xfs_da_args_t *args, |
| 769 | xfs_dir2_db_t db, /* directory block number */ | 694 | xfs_dir2_db_t db, |
| 770 | xfs_dabuf_t *bp) /* block's buffer */ | 695 | xfs_dabuf_t *bp) |
| 771 | { | 696 | { |
| 772 | xfs_fileoff_t bno; /* directory file offset */ | 697 | xfs_fileoff_t bno; /* directory file offset */ |
| 773 | xfs_dablk_t da; /* directory file offset */ | 698 | xfs_dablk_t da; /* directory file offset */ |
| 774 | int done; /* bunmap is finished */ | 699 | int done; /* bunmap is finished */ |
| 775 | xfs_inode_t *dp; /* incore directory inode */ | 700 | xfs_inode_t *dp; |
| 776 | int error; /* error return value */ | 701 | int error; |
| 777 | xfs_mount_t *mp; /* filesystem mount point */ | 702 | xfs_mount_t *mp; |
| 778 | xfs_trans_t *tp; /* transaction pointer */ | 703 | xfs_trans_t *tp; |
| 779 | 704 | ||
| 780 | xfs_dir2_trace_args_db("shrink_inode", args, db, bp); | 705 | xfs_dir2_trace_args_db("shrink_inode", args, db, bp); |
| 781 | dp = args->dp; | 706 | dp = args->dp; |
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h index 7dd364b1e038..86560b6f794c 100644 --- a/fs/xfs/xfs_dir2.h +++ b/fs/xfs/xfs_dir2.h | |||
| @@ -22,7 +22,9 @@ struct uio; | |||
| 22 | struct xfs_dabuf; | 22 | struct xfs_dabuf; |
| 23 | struct xfs_da_args; | 23 | struct xfs_da_args; |
| 24 | struct xfs_dir2_put_args; | 24 | struct xfs_dir2_put_args; |
| 25 | struct xfs_bmap_free; | ||
| 25 | struct xfs_inode; | 26 | struct xfs_inode; |
| 27 | struct xfs_mount; | ||
| 26 | struct xfs_trans; | 28 | struct xfs_trans; |
| 27 | 29 | ||
| 28 | /* | 30 | /* |
| @@ -73,7 +75,35 @@ typedef struct xfs_dir2_put_args { | |||
| 73 | } xfs_dir2_put_args_t; | 75 | } xfs_dir2_put_args_t; |
| 74 | 76 | ||
| 75 | /* | 77 | /* |
| 76 | * Other interfaces used by the rest of the dir v2 code. | 78 | * Generic directory interface routines |
| 79 | */ | ||
| 80 | extern void xfs_dir_startup(void); | ||
| 81 | extern void xfs_dir_mount(struct xfs_mount *mp); | ||
| 82 | extern int xfs_dir_isempty(struct xfs_inode *dp); | ||
| 83 | extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 84 | struct xfs_inode *pdp); | ||
| 85 | extern int xfs_dir_createname(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 86 | char *name, int namelen, xfs_ino_t inum, | ||
| 87 | xfs_fsblock_t *first, | ||
| 88 | struct xfs_bmap_free *flist, xfs_extlen_t tot); | ||
| 89 | extern int xfs_dir_lookup(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 90 | char *name, int namelen, xfs_ino_t *inum); | ||
| 91 | extern int xfs_dir_removename(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 92 | char *name, int namelen, xfs_ino_t ino, | ||
| 93 | xfs_fsblock_t *first, | ||
| 94 | struct xfs_bmap_free *flist, xfs_extlen_t tot); | ||
| 95 | extern int xfs_dir_getdents(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 96 | uio_t *uio, int *eofp); | ||
| 97 | extern int xfs_dir_replace(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 98 | char *name, int namelen, xfs_ino_t inum, | ||
| 99 | xfs_fsblock_t *first, | ||
| 100 | struct xfs_bmap_free *flist, xfs_extlen_t tot); | ||
| 101 | extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, | ||
| 102 | char *name, int namelen); | ||
| 103 | extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); | ||
| 104 | |||
| 105 | /* | ||
| 106 | * Utility routines for v2 directories. | ||
| 77 | */ | 107 | */ |
| 78 | extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, | 108 | extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, |
| 79 | xfs_dir2_db_t *dbp); | 109 | xfs_dir2_db_t *dbp); |
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 2621ff521dbd..9d7438bba30d 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
| @@ -22,19 +22,16 @@ | |||
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| 28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
| 30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_dir_sf.h" | ||
| 32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
| 33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
| 34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
| 35 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
| 36 | #include "xfs_inode_item.h" | 34 | #include "xfs_inode_item.h" |
| 37 | #include "xfs_dir_leaf.h" | ||
| 38 | #include "xfs_dir2_data.h" | 35 | #include "xfs_dir2_data.h" |
| 39 | #include "xfs_dir2_leaf.h" | 36 | #include "xfs_dir2_leaf.h" |
| 40 | #include "xfs_dir2_block.h" | 37 | #include "xfs_dir2_block.h" |
| @@ -51,6 +48,18 @@ static int xfs_dir2_block_lookup_int(xfs_da_args_t *args, xfs_dabuf_t **bpp, | |||
| 51 | int *entno); | 48 | int *entno); |
| 52 | static int xfs_dir2_block_sort(const void *a, const void *b); | 49 | static int xfs_dir2_block_sort(const void *a, const void *b); |
| 53 | 50 | ||
| 51 | static xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; | ||
| 52 | |||
| 53 | /* | ||
| 54 | * One-time startup routine called from xfs_init(). | ||
| 55 | */ | ||
| 56 | void | ||
| 57 | xfs_dir_startup(void) | ||
| 58 | { | ||
| 59 | xfs_dir_hash_dot = xfs_da_hashname(".", 1); | ||
| 60 | xfs_dir_hash_dotdot = xfs_da_hashname("..", 2); | ||
| 61 | } | ||
| 62 | |||
| 54 | /* | 63 | /* |
| 55 | * Add an entry to a block directory. | 64 | * Add an entry to a block directory. |
| 56 | */ | 65 | */ |
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index 7be37d38961f..f7c799217072 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c | |||
| @@ -22,18 +22,15 @@ | |||
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| 28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
| 30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_dir_sf.h" | ||
| 32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
| 33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
| 34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
| 35 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
| 36 | #include "xfs_dir_leaf.h" | ||
| 37 | #include "xfs_dir2_data.h" | 34 | #include "xfs_dir2_data.h" |
| 38 | #include "xfs_dir2_leaf.h" | 35 | #include "xfs_dir2_leaf.h" |
| 39 | #include "xfs_dir2_block.h" | 36 | #include "xfs_dir2_block.h" |
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 74ef99f2ee5f..b1cf1fbf423d 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.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_da_btree.h" | 30 | #include "xfs_da_btree.h" |
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_attr_sf.h" | 32 | #include "xfs_attr_sf.h" |
| 34 | #include "xfs_dir_sf.h" | ||
| 35 | #include "xfs_dir2_sf.h" | 33 | #include "xfs_dir2_sf.h" |
| 36 | #include "xfs_dinode.h" | 34 | #include "xfs_dinode.h" |
| 37 | #include "xfs_inode.h" | 35 | #include "xfs_inode.h" |
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index b1f85cc7795a..9ca71719b683 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c | |||
| @@ -22,13 +22,11 @@ | |||
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| 28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
| 30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_dir_sf.h" | ||
| 32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
| 33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
| 34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index 06afa1b324cf..0cd77b17bf92 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c | |||
| @@ -22,19 +22,16 @@ | |||
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| 28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
| 30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_dir_sf.h" | ||
| 32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
| 33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
| 34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
| 35 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
| 36 | #include "xfs_inode_item.h" | 34 | #include "xfs_inode_item.h" |
| 37 | #include "xfs_dir_leaf.h" | ||
| 38 | #include "xfs_error.h" | 35 | #include "xfs_error.h" |
| 39 | #include "xfs_dir2_data.h" | 36 | #include "xfs_dir2_data.h" |
| 40 | #include "xfs_dir2_leaf.h" | 37 | #include "xfs_dir2_leaf.h" |
diff --git a/fs/xfs/xfs_dir2_trace.c b/fs/xfs/xfs_dir2_trace.c index c626943b4112..f3fb2ffd6f5c 100644 --- a/fs/xfs/xfs_dir2_trace.c +++ b/fs/xfs/xfs_dir2_trace.c | |||
| @@ -19,11 +19,9 @@ | |||
| 19 | #include "xfs_fs.h" | 19 | #include "xfs_fs.h" |
| 20 | #include "xfs_types.h" | 20 | #include "xfs_types.h" |
| 21 | #include "xfs_inum.h" | 21 | #include "xfs_inum.h" |
| 22 | #include "xfs_dir.h" | ||
| 23 | #include "xfs_dir2.h" | 22 | #include "xfs_dir2.h" |
| 24 | #include "xfs_da_btree.h" | 23 | #include "xfs_da_btree.h" |
| 25 | #include "xfs_bmap_btree.h" | 24 | #include "xfs_bmap_btree.h" |
| 26 | #include "xfs_dir_sf.h" | ||
| 27 | #include "xfs_dir2_sf.h" | 25 | #include "xfs_dir2_sf.h" |
| 28 | #include "xfs_attr_sf.h" | 26 | #include "xfs_attr_sf.h" |
| 29 | #include "xfs_dinode.h" | 27 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c index e7121040cd9d..e69de29bb2d1 100644 --- a/fs/xfs/xfs_dir_leaf.c +++ b/fs/xfs/xfs_dir_leaf.c | |||
| @@ -1,2230 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write the Free Software Foundation, | ||
| 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | #include "xfs.h" | ||
| 19 | #include "xfs_fs.h" | ||
| 20 | #include "xfs_types.h" | ||
| 21 | #include "xfs_log.h" | ||
| 22 | #include "xfs_inum.h" | ||
| 23 | #include "xfs_trans.h" | ||
| 24 | #include "xfs_sb.h" | ||
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dir2.h" | ||
| 27 | #include "xfs_dmapi.h" | ||
| 28 | #include "xfs_mount.h" | ||
| 29 | #include "xfs_da_btree.h" | ||
| 30 | #include "xfs_bmap_btree.h" | ||
| 31 | #include "xfs_alloc_btree.h" | ||
| 32 | #include "xfs_ialloc_btree.h" | ||
| 33 | #include "xfs_dir_sf.h" | ||
| 34 | #include "xfs_dir2_sf.h" | ||
| 35 | #include "xfs_attr_sf.h" | ||
| 36 | #include "xfs_dinode.h" | ||
| 37 | #include "xfs_inode.h" | ||
| 38 | #include "xfs_inode_item.h" | ||
| 39 | #include "xfs_alloc.h" | ||
| 40 | #include "xfs_btree.h" | ||
| 41 | #include "xfs_bmap.h" | ||
| 42 | #include "xfs_dir_leaf.h" | ||
| 43 | #include "xfs_error.h" | ||
| 44 | |||
| 45 | /* | ||
| 46 | * xfs_dir_leaf.c | ||
| 47 | * | ||
| 48 | * Routines to implement leaf blocks of directories as Btrees of hashed names. | ||
| 49 | */ | ||
| 50 | |||
| 51 | /*======================================================================== | ||
| 52 | * Function prototypes for the kernel. | ||
| 53 | *========================================================================*/ | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Routines used for growing the Btree. | ||
| 57 | */ | ||
| 58 | STATIC void xfs_dir_leaf_add_work(xfs_dabuf_t *leaf_buffer, xfs_da_args_t *args, | ||
| 59 | int insertion_index, | ||
| 60 | int freemap_index); | ||
| 61 | STATIC int xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *leaf_buffer, | ||
| 62 | int musthave, int justcheck); | ||
| 63 | STATIC void xfs_dir_leaf_rebalance(xfs_da_state_t *state, | ||
| 64 | xfs_da_state_blk_t *blk1, | ||
| 65 | xfs_da_state_blk_t *blk2); | ||
| 66 | STATIC int xfs_dir_leaf_figure_balance(xfs_da_state_t *state, | ||
| 67 | xfs_da_state_blk_t *leaf_blk_1, | ||
| 68 | xfs_da_state_blk_t *leaf_blk_2, | ||
| 69 | int *number_entries_in_blk1, | ||
| 70 | int *number_namebytes_in_blk1); | ||
| 71 | |||
| 72 | STATIC int xfs_dir_leaf_create(struct xfs_da_args *args, | ||
| 73 | xfs_dablk_t which_block, | ||
| 74 | struct xfs_dabuf **bpp); | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Utility routines. | ||
| 78 | */ | ||
| 79 | STATIC void xfs_dir_leaf_moveents(xfs_dir_leafblock_t *src_leaf, | ||
| 80 | int src_start, | ||
| 81 | xfs_dir_leafblock_t *dst_leaf, | ||
| 82 | int dst_start, int move_count, | ||
| 83 | xfs_mount_t *mp); | ||
| 84 | |||
| 85 | |||
| 86 | /*======================================================================== | ||
| 87 | * External routines when dirsize < XFS_IFORK_DSIZE(dp). | ||
| 88 | *========================================================================*/ | ||
| 89 | |||
| 90 | |||
| 91 | /* | ||
| 92 | * Validate a given inode number. | ||
| 93 | */ | ||
| 94 | int | ||
| 95 | xfs_dir_ino_validate(xfs_mount_t *mp, xfs_ino_t ino) | ||
| 96 | { | ||
| 97 | xfs_agblock_t agblkno; | ||
| 98 | xfs_agino_t agino; | ||
| 99 | xfs_agnumber_t agno; | ||
| 100 | int ino_ok; | ||
| 101 | int ioff; | ||
| 102 | |||
| 103 | agno = XFS_INO_TO_AGNO(mp, ino); | ||
| 104 | agblkno = XFS_INO_TO_AGBNO(mp, ino); | ||
| 105 | ioff = XFS_INO_TO_OFFSET(mp, ino); | ||
| 106 | agino = XFS_OFFBNO_TO_AGINO(mp, agblkno, ioff); | ||
| 107 | ino_ok = | ||
| 108 | agno < mp->m_sb.sb_agcount && | ||
| 109 | agblkno < mp->m_sb.sb_agblocks && | ||
| 110 | agblkno != 0 && | ||
| 111 | ioff < (1 << mp->m_sb.sb_inopblog) && | ||
| 112 | XFS_AGINO_TO_INO(mp, agno, agino) == ino; | ||
| 113 | if (unlikely(XFS_TEST_ERROR(!ino_ok, mp, XFS_ERRTAG_DIR_INO_VALIDATE, | ||
| 114 | XFS_RANDOM_DIR_INO_VALIDATE))) { | ||
| 115 | xfs_fs_cmn_err(CE_WARN, mp, "Invalid inode number 0x%Lx", | ||
| 116 | (unsigned long long) ino); | ||
| 117 | XFS_ERROR_REPORT("xfs_dir_ino_validate", XFS_ERRLEVEL_LOW, mp); | ||
| 118 | return XFS_ERROR(EFSCORRUPTED); | ||
| 119 | } | ||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | /* | ||
| 124 | * Create the initial contents of a shortform directory. | ||
| 125 | */ | ||
| 126 | int | ||
| 127 | xfs_dir_shortform_create(xfs_da_args_t *args, xfs_ino_t parent) | ||
| 128 | { | ||
| 129 | xfs_dir_sf_hdr_t *hdr; | ||
| 130 | xfs_inode_t *dp; | ||
| 131 | |||
| 132 | dp = args->dp; | ||
| 133 | ASSERT(dp != NULL); | ||
| 134 | ASSERT(dp->i_d.di_size == 0); | ||
| 135 | if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { | ||
| 136 | dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */ | ||
| 137 | dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; | ||
| 138 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); | ||
| 139 | dp->i_df.if_flags |= XFS_IFINLINE; | ||
| 140 | } | ||
| 141 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
| 142 | ASSERT(dp->i_df.if_bytes == 0); | ||
| 143 | xfs_idata_realloc(dp, sizeof(*hdr), XFS_DATA_FORK); | ||
| 144 | hdr = (xfs_dir_sf_hdr_t *)dp->i_df.if_u1.if_data; | ||
| 145 | XFS_DIR_SF_PUT_DIRINO(&parent, &hdr->parent); | ||
| 146 | |||
| 147 | hdr->count = 0; | ||
| 148 | dp->i_d.di_size = sizeof(*hdr); | ||
| 149 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); | ||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Add a name to the shortform directory structure. | ||
| 155 | * Overflow from the inode has already been checked for. | ||
| 156 | */ | ||
| 157 | int | ||
| 158 | xfs_dir_shortform_addname(xfs_da_args_t *args) | ||
| 159 | { | ||
| 160 | xfs_dir_shortform_t *sf; | ||
| 161 | xfs_dir_sf_entry_t *sfe; | ||
| 162 | int i, offset, size; | ||
| 163 | xfs_inode_t *dp; | ||
| 164 | |||
| 165 | dp = args->dp; | ||
| 166 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
| 167 | /* | ||
| 168 | * Catch the case where the conversion from shortform to leaf | ||
| 169 | * failed part way through. | ||
| 170 | */ | ||
| 171 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
| 172 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
| 173 | return XFS_ERROR(EIO); | ||
| 174 | } | ||
| 175 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
| 176 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
| 177 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
| 178 | sfe = &sf->list[0]; | ||
| 179 | for (i = sf->hdr.count-1; i >= 0; i--) { | ||
| 180 | if (sfe->namelen == args->namelen && | ||
| 181 | args->name[0] == sfe->name[0] && | ||
| 182 | memcmp(args->name, sfe->name, args->namelen) == 0) | ||
| 183 | return XFS_ERROR(EEXIST); | ||
| 184 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
| 185 | } | ||
| 186 | |||
| 187 | offset = (int)((char *)sfe - (char *)sf); | ||
| 188 | size = XFS_DIR_SF_ENTSIZE_BYNAME(args->namelen); | ||
| 189 | xfs_idata_realloc(dp, size, XFS_DATA_FORK); | ||
| 190 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
| 191 | sfe = (xfs_dir_sf_entry_t *)((char *)sf + offset); | ||
| 192 | |||
| 193 | XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber); | ||
| 194 | sfe->namelen = args->namelen; | ||
| 195 | memcpy(sfe->name, args->name, sfe->namelen); | ||
| 196 | sf->hdr.count++; | ||
| 197 | |||
| 198 | dp->i_d.di_size += size; | ||
| 199 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); | ||
| 200 | |||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | /* | ||
| 205 | * Remove a name from the shortform directory structure. | ||
| 206 | */ | ||
| 207 | int | ||
| 208 | xfs_dir_shortform_removename(xfs_da_args_t *args) | ||
| 209 | { | ||
| 210 | xfs_dir_shortform_t *sf; | ||
| 211 | xfs_dir_sf_entry_t *sfe; | ||
| 212 | int base, size = 0, i; | ||
| 213 | xfs_inode_t *dp; | ||
| 214 | |||
| 215 | dp = args->dp; | ||
| 216 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
| 217 | /* | ||
| 218 | * Catch the case where the conversion from shortform to leaf | ||
| 219 | * failed part way through. | ||
| 220 | */ | ||
| 221 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
| 222 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
| 223 | return XFS_ERROR(EIO); | ||
| 224 | } | ||
| 225 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
| 226 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
| 227 | base = sizeof(xfs_dir_sf_hdr_t); | ||
| 228 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
| 229 | sfe = &sf->list[0]; | ||
| 230 | for (i = sf->hdr.count-1; i >= 0; i--) { | ||
| 231 | size = XFS_DIR_SF_ENTSIZE_BYENTRY(sfe); | ||
| 232 | if (sfe->namelen == args->namelen && | ||
| 233 | sfe->name[0] == args->name[0] && | ||
| 234 | memcmp(sfe->name, args->name, args->namelen) == 0) | ||
| 235 | break; | ||
| 236 | base += size; | ||
| 237 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
| 238 | } | ||
| 239 | if (i < 0) { | ||
| 240 | ASSERT(args->oknoent); | ||
| 241 | return XFS_ERROR(ENOENT); | ||
| 242 | } | ||
| 243 | |||
| 244 | if ((base + size) != dp->i_d.di_size) { | ||
| 245 | memmove(&((char *)sf)[base], &((char *)sf)[base+size], | ||
| 246 | dp->i_d.di_size - (base+size)); | ||
| 247 | } | ||
| 248 | sf->hdr.count--; | ||
| 249 | |||
| 250 | xfs_idata_realloc(dp, -size, XFS_DATA_FORK); | ||
| 251 | dp->i_d.di_size -= size; | ||
| 252 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); | ||
| 253 | |||
| 254 | return 0; | ||
| 255 | } | ||
| 256 | |||
| 257 | /* | ||
| 258 | * Look up a name in a shortform directory structure. | ||
| 259 | */ | ||
| 260 | int | ||
| 261 | xfs_dir_shortform_lookup(xfs_da_args_t *args) | ||
| 262 | { | ||
| 263 | xfs_dir_shortform_t *sf; | ||
| 264 | xfs_dir_sf_entry_t *sfe; | ||
| 265 | int i; | ||
| 266 | xfs_inode_t *dp; | ||
| 267 | |||
| 268 | dp = args->dp; | ||
| 269 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
| 270 | /* | ||
| 271 | * Catch the case where the conversion from shortform to leaf | ||
| 272 | * failed part way through. | ||
| 273 | */ | ||
| 274 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
| 275 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
| 276 | return XFS_ERROR(EIO); | ||
| 277 | } | ||
| 278 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
| 279 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
| 280 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
| 281 | if (args->namelen == 2 && | ||
| 282 | args->name[0] == '.' && args->name[1] == '.') { | ||
| 283 | XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &args->inumber); | ||
| 284 | return(XFS_ERROR(EEXIST)); | ||
| 285 | } | ||
| 286 | if (args->namelen == 1 && args->name[0] == '.') { | ||
| 287 | args->inumber = dp->i_ino; | ||
| 288 | return(XFS_ERROR(EEXIST)); | ||
| 289 | } | ||
| 290 | sfe = &sf->list[0]; | ||
| 291 | for (i = sf->hdr.count-1; i >= 0; i--) { | ||
| 292 | if (sfe->namelen == args->namelen && | ||
| 293 | sfe->name[0] == args->name[0] && | ||
| 294 | memcmp(args->name, sfe->name, args->namelen) == 0) { | ||
| 295 | XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args->inumber); | ||
| 296 | return(XFS_ERROR(EEXIST)); | ||
| 297 | } | ||
| 298 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
| 299 | } | ||
| 300 | ASSERT(args->oknoent); | ||
| 301 | return(XFS_ERROR(ENOENT)); | ||
| 302 | } | ||
| 303 | |||
| 304 | /* | ||
| 305 | * Convert from using the shortform to the leaf. | ||
| 306 | */ | ||
| 307 | int | ||
| 308 | xfs_dir_shortform_to_leaf(xfs_da_args_t *iargs) | ||
| 309 | { | ||
| 310 | xfs_inode_t *dp; | ||
| 311 | xfs_dir_shortform_t *sf; | ||
| 312 | xfs_dir_sf_entry_t *sfe; | ||
| 313 | xfs_da_args_t args; | ||
| 314 | xfs_ino_t inumber; | ||
| 315 | char *tmpbuffer; | ||
| 316 | int retval, i, size; | ||
| 317 | xfs_dablk_t blkno; | ||
| 318 | xfs_dabuf_t *bp; | ||
| 319 | |||
| 320 | dp = iargs->dp; | ||
| 321 | /* | ||
| 322 | * Catch the case where the conversion from shortform to leaf | ||
| 323 | * failed part way through. | ||
| 324 | */ | ||
| 325 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
| 326 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
| 327 | return XFS_ERROR(EIO); | ||
| 328 | } | ||
| 329 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
| 330 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
| 331 | size = dp->i_df.if_bytes; | ||
| 332 | tmpbuffer = kmem_alloc(size, KM_SLEEP); | ||
| 333 | ASSERT(tmpbuffer != NULL); | ||
| 334 | |||
| 335 | memcpy(tmpbuffer, dp->i_df.if_u1.if_data, size); | ||
| 336 | |||
| 337 | sf = (xfs_dir_shortform_t *)tmpbuffer; | ||
| 338 | XFS_DIR_SF_GET_DIRINO(&sf->hdr.parent, &inumber); | ||
| 339 | |||
| 340 | xfs_idata_realloc(dp, -size, XFS_DATA_FORK); | ||
| 341 | dp->i_d.di_size = 0; | ||
| 342 | xfs_trans_log_inode(iargs->trans, dp, XFS_ILOG_CORE); | ||
| 343 | retval = xfs_da_grow_inode(iargs, &blkno); | ||
| 344 | if (retval) | ||
| 345 | goto out; | ||
| 346 | |||
| 347 | ASSERT(blkno == 0); | ||
| 348 | retval = xfs_dir_leaf_create(iargs, blkno, &bp); | ||
| 349 | if (retval) | ||
| 350 | goto out; | ||
| 351 | xfs_da_buf_done(bp); | ||
| 352 | |||
| 353 | args.name = "."; | ||
| 354 | args.namelen = 1; | ||
| 355 | args.hashval = xfs_dir_hash_dot; | ||
| 356 | args.inumber = dp->i_ino; | ||
| 357 | args.dp = dp; | ||
| 358 | args.firstblock = iargs->firstblock; | ||
| 359 | args.flist = iargs->flist; | ||
| 360 | args.total = iargs->total; | ||
| 361 | args.whichfork = XFS_DATA_FORK; | ||
| 362 | args.trans = iargs->trans; | ||
| 363 | args.justcheck = 0; | ||
| 364 | args.addname = args.oknoent = 1; | ||
| 365 | retval = xfs_dir_leaf_addname(&args); | ||
| 366 | if (retval) | ||
| 367 | goto out; | ||
| 368 | |||
| 369 | args.name = ".."; | ||
| 370 | args.namelen = 2; | ||
| 371 | args.hashval = xfs_dir_hash_dotdot; | ||
| 372 | args.inumber = inumber; | ||
| 373 | retval = xfs_dir_leaf_addname(&args); | ||
| 374 | if (retval) | ||
| 375 | goto out; | ||
| 376 | |||
| 377 | sfe = &sf->list[0]; | ||
| 378 | for (i = 0; i < sf->hdr.count; i++) { | ||
| 379 | args.name = (char *)(sfe->name); | ||
| 380 | args.namelen = sfe->namelen; | ||
| 381 | args.hashval = xfs_da_hashname((char *)(sfe->name), | ||
| 382 | sfe->namelen); | ||
| 383 | XFS_DIR_SF_GET_DIRINO(&sfe->inumber, &args.inumber); | ||
| 384 | retval = xfs_dir_leaf_addname(&args); | ||
| 385 | if (retval) | ||
| 386 | goto out; | ||
| 387 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
| 388 | } | ||
| 389 | retval = 0; | ||
| 390 | |||
| 391 | out: | ||
| 392 | kmem_free(tmpbuffer, size); | ||
| 393 | return retval; | ||
| 394 | } | ||
| 395 | |||
| 396 | STATIC int | ||
| 397 | xfs_dir_shortform_compare(const void *a, const void *b) | ||
| 398 | { | ||
| 399 | xfs_dir_sf_sort_t *sa, *sb; | ||
| 400 | |||
| 401 | sa = (xfs_dir_sf_sort_t *)a; | ||
| 402 | sb = (xfs_dir_sf_sort_t *)b; | ||
| 403 | if (sa->hash < sb->hash) | ||
| 404 | return -1; | ||
| 405 | else if (sa->hash > sb->hash) | ||
| 406 | return 1; | ||
| 407 | else | ||
| 408 | return sa->entno - sb->entno; | ||
| 409 | } | ||
| 410 | |||
| 411 | /* | ||
| 412 | * Copy out directory entries for getdents(), for shortform directories. | ||
| 413 | */ | ||
| 414 | /*ARGSUSED*/ | ||
| 415 | int | ||
| 416 | xfs_dir_shortform_getdents(xfs_inode_t *dp, uio_t *uio, int *eofp, | ||
| 417 | xfs_dirent_t *dbp, xfs_dir_put_t put) | ||
| 418 | { | ||
| 419 | xfs_dir_shortform_t *sf; | ||
| 420 | xfs_dir_sf_entry_t *sfe; | ||
| 421 | int retval, i, sbsize, nsbuf, lastresid=0, want_entno; | ||
| 422 | xfs_mount_t *mp; | ||
| 423 | xfs_dahash_t cookhash, hash; | ||
| 424 | xfs_dir_put_args_t p; | ||
| 425 | xfs_dir_sf_sort_t *sbuf, *sbp; | ||
| 426 | |||
| 427 | mp = dp->i_mount; | ||
| 428 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
| 429 | cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset); | ||
| 430 | want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset); | ||
| 431 | nsbuf = sf->hdr.count + 2; | ||
| 432 | sbsize = (nsbuf + 1) * sizeof(*sbuf); | ||
| 433 | sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP); | ||
| 434 | |||
| 435 | xfs_dir_trace_g_du("sf: start", dp, uio); | ||
| 436 | |||
| 437 | /* | ||
| 438 | * Collect all the entries into the buffer. | ||
| 439 | * Entry 0 is . | ||
| 440 | */ | ||
| 441 | sbp->entno = 0; | ||
| 442 | sbp->seqno = 0; | ||
| 443 | sbp->hash = xfs_dir_hash_dot; | ||
| 444 | sbp->ino = dp->i_ino; | ||
| 445 | sbp->name = "."; | ||
| 446 | sbp->namelen = 1; | ||
| 447 | sbp++; | ||
| 448 | |||
| 449 | /* | ||
| 450 | * Entry 1 is .. | ||
| 451 | */ | ||
| 452 | sbp->entno = 1; | ||
| 453 | sbp->seqno = 0; | ||
| 454 | sbp->hash = xfs_dir_hash_dotdot; | ||
| 455 | sbp->ino = XFS_GET_DIR_INO8(sf->hdr.parent); | ||
| 456 | sbp->name = ".."; | ||
| 457 | sbp->namelen = 2; | ||
| 458 | sbp++; | ||
| 459 | |||
| 460 | /* | ||
| 461 | * Scan the directory data for the rest of the entries. | ||
| 462 | */ | ||
| 463 | for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) { | ||
| 464 | |||
| 465 | if (unlikely( | ||
| 466 | ((char *)sfe < (char *)sf) || | ||
| 467 | ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)))) { | ||
| 468 | xfs_dir_trace_g_du("sf: corrupted", dp, uio); | ||
| 469 | XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents", | ||
| 470 | XFS_ERRLEVEL_LOW, mp, sfe); | ||
| 471 | kmem_free(sbuf, sbsize); | ||
| 472 | return XFS_ERROR(EFSCORRUPTED); | ||
| 473 | } | ||
| 474 | |||
| 475 | sbp->entno = i + 2; | ||
| 476 | sbp->seqno = 0; | ||
| 477 | sbp->hash = xfs_da_hashname((char *)sfe->name, sfe->namelen); | ||
| 478 | sbp->ino = XFS_GET_DIR_INO8(sfe->inumber); | ||
| 479 | sbp->name = (char *)sfe->name; | ||
| 480 | sbp->namelen = sfe->namelen; | ||
| 481 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
| 482 | sbp++; | ||
| 483 | } | ||
| 484 | |||
| 485 | /* | ||
| 486 | * Sort the entries on hash then entno. | ||
| 487 | */ | ||
| 488 | xfs_sort(sbuf, nsbuf, sizeof(*sbuf), xfs_dir_shortform_compare); | ||
| 489 | /* | ||
| 490 | * Stuff in last entry. | ||
| 491 | */ | ||
| 492 | sbp->entno = nsbuf; | ||
| 493 | sbp->hash = XFS_DA_MAXHASH; | ||
| 494 | sbp->seqno = 0; | ||
| 495 | /* | ||
| 496 | * Figure out the sequence numbers in case there's a hash duplicate. | ||
| 497 | */ | ||
| 498 | for (hash = sbuf->hash, sbp = sbuf + 1; | ||
| 499 | sbp < &sbuf[nsbuf + 1]; sbp++) { | ||
| 500 | if (sbp->hash == hash) | ||
| 501 | sbp->seqno = sbp[-1].seqno + 1; | ||
| 502 | else | ||
| 503 | hash = sbp->hash; | ||
| 504 | } | ||
| 505 | |||
| 506 | /* | ||
| 507 | * Set up put routine. | ||
| 508 | */ | ||
| 509 | p.dbp = dbp; | ||
| 510 | p.put = put; | ||
| 511 | p.uio = uio; | ||
| 512 | |||
| 513 | /* | ||
| 514 | * Find our place. | ||
| 515 | */ | ||
| 516 | for (sbp = sbuf; sbp < &sbuf[nsbuf + 1]; sbp++) { | ||
| 517 | if (sbp->hash > cookhash || | ||
| 518 | (sbp->hash == cookhash && sbp->seqno >= want_entno)) | ||
| 519 | break; | ||
| 520 | } | ||
| 521 | |||
| 522 | /* | ||
| 523 | * Did we fail to find anything? We stop at the last entry, | ||
| 524 | * the one we put maxhash into. | ||
| 525 | */ | ||
| 526 | if (sbp == &sbuf[nsbuf]) { | ||
| 527 | kmem_free(sbuf, sbsize); | ||
| 528 | xfs_dir_trace_g_du("sf: hash beyond end", dp, uio); | ||
| 529 | uio->uio_offset = XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH); | ||
| 530 | *eofp = 1; | ||
| 531 | return 0; | ||
| 532 | } | ||
| 533 | |||
| 534 | /* | ||
| 535 | * Loop putting entries into the user buffer. | ||
| 536 | */ | ||
| 537 | while (sbp < &sbuf[nsbuf]) { | ||
| 538 | /* | ||
| 539 | * Save the first resid in a run of equal-hashval entries | ||
| 540 | * so that we can back them out if they don't all fit. | ||
| 541 | */ | ||
| 542 | if (sbp->seqno == 0 || sbp == sbuf) | ||
| 543 | lastresid = uio->uio_resid; | ||
| 544 | XFS_PUT_COOKIE(p.cook, mp, 0, sbp[1].seqno, sbp[1].hash); | ||
| 545 | p.ino = sbp->ino; | ||
| 546 | #if XFS_BIG_INUMS | ||
| 547 | p.ino += mp->m_inoadd; | ||
| 548 | #endif | ||
| 549 | p.name = sbp->name; | ||
| 550 | p.namelen = sbp->namelen; | ||
| 551 | retval = p.put(&p); | ||
| 552 | if (!p.done) { | ||
| 553 | uio->uio_offset = | ||
| 554 | XFS_DA_MAKE_COOKIE(mp, 0, 0, sbp->hash); | ||
| 555 | kmem_free(sbuf, sbsize); | ||
| 556 | uio->uio_resid = lastresid; | ||
| 557 | xfs_dir_trace_g_du("sf: E-O-B", dp, uio); | ||
| 558 | return retval; | ||
| 559 | } | ||
| 560 | sbp++; | ||
| 561 | } | ||
| 562 | kmem_free(sbuf, sbsize); | ||
| 563 | uio->uio_offset = p.cook.o; | ||
| 564 | *eofp = 1; | ||
| 565 | xfs_dir_trace_g_du("sf: E-O-F", dp, uio); | ||
| 566 | return 0; | ||
| 567 | } | ||
| 568 | |||
| 569 | /* | ||
| 570 | * Look up a name in a shortform directory structure, replace the inode number. | ||
| 571 | */ | ||
| 572 | int | ||
| 573 | xfs_dir_shortform_replace(xfs_da_args_t *args) | ||
| 574 | { | ||
| 575 | xfs_dir_shortform_t *sf; | ||
| 576 | xfs_dir_sf_entry_t *sfe; | ||
| 577 | xfs_inode_t *dp; | ||
| 578 | int i; | ||
| 579 | |||
| 580 | dp = args->dp; | ||
| 581 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | ||
| 582 | /* | ||
| 583 | * Catch the case where the conversion from shortform to leaf | ||
| 584 | * failed part way through. | ||
| 585 | */ | ||
| 586 | if (dp->i_d.di_size < sizeof(xfs_dir_sf_hdr_t)) { | ||
| 587 | ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); | ||
| 588 | return XFS_ERROR(EIO); | ||
| 589 | } | ||
| 590 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | ||
| 591 | ASSERT(dp->i_df.if_u1.if_data != NULL); | ||
| 592 | sf = (xfs_dir_shortform_t *)dp->i_df.if_u1.if_data; | ||
| 593 | if (args->namelen == 2 && | ||
| 594 | args->name[0] == '.' && args->name[1] == '.') { | ||
| 595 | /* XXX - replace assert? */ | ||
| 596 | XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sf->hdr.parent); | ||
| 597 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); | ||
| 598 | return 0; | ||
| 599 | } | ||
| 600 | ASSERT(args->namelen != 1 || args->name[0] != '.'); | ||
| 601 | sfe = &sf->list[0]; | ||
| 602 | for (i = sf->hdr.count-1; i >= 0; i--) { | ||
| 603 | if (sfe->namelen == args->namelen && | ||
| 604 | sfe->name[0] == args->name[0] && | ||
| 605 | memcmp(args->name, sfe->name, args->namelen) == 0) { | ||
| 606 | ASSERT(memcmp((char *)&args->inumber, | ||
| 607 | (char *)&sfe->inumber, sizeof(xfs_ino_t))); | ||
| 608 | XFS_DIR_SF_PUT_DIRINO(&args->inumber, &sfe->inumber); | ||
| 609 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_DDATA); | ||
| 610 | return 0; | ||
| 611 | } | ||
| 612 | sfe = XFS_DIR_SF_NEXTENTRY(sfe); | ||
| 613 | } | ||
| 614 | ASSERT(args->oknoent); | ||
| 615 | return XFS_ERROR(ENOENT); | ||
| 616 | } | ||
| 617 | |||
| 618 | /* | ||
| 619 | * Convert a leaf directory to shortform structure | ||
| 620 | */ | ||
| 621 | int | ||
| 622 | xfs_dir_leaf_to_shortform(xfs_da_args_t *iargs) | ||
| 623 | { | ||
| 624 | xfs_dir_leafblock_t *leaf; | ||
| 625 | xfs_dir_leaf_hdr_t *hdr; | ||
| 626 | xfs_dir_leaf_entry_t *entry; | ||
| 627 | xfs_dir_leaf_name_t *namest; | ||
| 628 | xfs_da_args_t args; | ||
| 629 | xfs_inode_t *dp; | ||
| 630 | xfs_ino_t parent = 0; | ||
| 631 | char *tmpbuffer; | ||
| 632 | int retval, i; | ||
| 633 | xfs_dabuf_t *bp; | ||
| 634 | |||
| 635 | dp = iargs->dp; | ||
| 636 | tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); | ||
| 637 | ASSERT(tmpbuffer != NULL); | ||
| 638 | |||
| 639 | retval = xfs_da_read_buf(iargs->trans, iargs->dp, 0, -1, &bp, | ||
| 640 | XFS_DATA_FORK); | ||
| 641 | if (retval) | ||
| 642 | goto out; | ||
| 643 | ASSERT(bp != NULL); | ||
| 644 | memcpy(tmpbuffer, bp->data, XFS_LBSIZE(dp->i_mount)); | ||
| 645 | leaf = (xfs_dir_leafblock_t *)tmpbuffer; | ||
| 646 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 647 | memset(bp->data, 0, XFS_LBSIZE(dp->i_mount)); | ||
| 648 | |||
| 649 | /* | ||
| 650 | * Find and special case the parent inode number | ||
| 651 | */ | ||
| 652 | hdr = &leaf->hdr; | ||
| 653 | entry = &leaf->entries[0]; | ||
| 654 | for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) { | ||
| 655 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); | ||
| 656 | if ((entry->namelen == 2) && | ||
| 657 | (namest->name[0] == '.') && | ||
| 658 | (namest->name[1] == '.')) { | ||
| 659 | XFS_DIR_SF_GET_DIRINO(&namest->inumber, &parent); | ||
| 660 | entry->nameidx = 0; | ||
| 661 | } else if ((entry->namelen == 1) && (namest->name[0] == '.')) { | ||
| 662 | entry->nameidx = 0; | ||
| 663 | } | ||
| 664 | } | ||
| 665 | retval = xfs_da_shrink_inode(iargs, 0, bp); | ||
| 666 | if (retval) | ||
| 667 | goto out; | ||
| 668 | retval = xfs_dir_shortform_create(iargs, parent); | ||
| 669 | if (retval) | ||
| 670 | goto out; | ||
| 671 | |||
| 672 | /* | ||
| 673 | * Copy the rest of the filenames | ||
| 674 | */ | ||
| 675 | entry = &leaf->entries[0]; | ||
| 676 | args.dp = dp; | ||
| 677 | args.firstblock = iargs->firstblock; | ||
| 678 | args.flist = iargs->flist; | ||
| 679 | args.total = iargs->total; | ||
| 680 | args.whichfork = XFS_DATA_FORK; | ||
| 681 | args.trans = iargs->trans; | ||
| 682 | args.justcheck = 0; | ||
| 683 | args.addname = args.oknoent = 1; | ||
| 684 | for (i = 0; i < be16_to_cpu(hdr->count); entry++, i++) { | ||
| 685 | if (!entry->nameidx) | ||
| 686 | continue; | ||
| 687 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); | ||
| 688 | args.name = (char *)(namest->name); | ||
| 689 | args.namelen = entry->namelen; | ||
| 690 | args.hashval = be32_to_cpu(entry->hashval); | ||
| 691 | XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args.inumber); | ||
| 692 | xfs_dir_shortform_addname(&args); | ||
| 693 | } | ||
| 694 | |||
| 695 | out: | ||
| 696 | kmem_free(tmpbuffer, XFS_LBSIZE(dp->i_mount)); | ||
| 697 | return retval; | ||
| 698 | } | ||
| 699 | |||
| 700 | /* | ||
| 701 | * Convert from using a single leaf to a root node and a leaf. | ||
| 702 | */ | ||
| 703 | int | ||
| 704 | xfs_dir_leaf_to_node(xfs_da_args_t *args) | ||
| 705 | { | ||
| 706 | xfs_dir_leafblock_t *leaf; | ||
| 707 | xfs_da_intnode_t *node; | ||
| 708 | xfs_inode_t *dp; | ||
| 709 | xfs_dabuf_t *bp1, *bp2; | ||
| 710 | xfs_dablk_t blkno; | ||
| 711 | int retval; | ||
| 712 | |||
| 713 | dp = args->dp; | ||
| 714 | retval = xfs_da_grow_inode(args, &blkno); | ||
| 715 | ASSERT(blkno == 1); | ||
| 716 | if (retval) | ||
| 717 | return retval; | ||
| 718 | retval = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp1, | ||
| 719 | XFS_DATA_FORK); | ||
| 720 | if (retval) | ||
| 721 | return retval; | ||
| 722 | ASSERT(bp1 != NULL); | ||
| 723 | retval = xfs_da_get_buf(args->trans, args->dp, 1, -1, &bp2, | ||
| 724 | XFS_DATA_FORK); | ||
| 725 | if (retval) { | ||
| 726 | xfs_da_buf_done(bp1); | ||
| 727 | return retval; | ||
| 728 | } | ||
| 729 | ASSERT(bp2 != NULL); | ||
| 730 | memcpy(bp2->data, bp1->data, XFS_LBSIZE(dp->i_mount)); | ||
| 731 | xfs_da_buf_done(bp1); | ||
| 732 | xfs_da_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); | ||
| 733 | |||
| 734 | /* | ||
| 735 | * Set up the new root node. | ||
| 736 | */ | ||
| 737 | retval = xfs_da_node_create(args, 0, 1, &bp1, XFS_DATA_FORK); | ||
| 738 | if (retval) { | ||
| 739 | xfs_da_buf_done(bp2); | ||
| 740 | return retval; | ||
| 741 | } | ||
| 742 | node = bp1->data; | ||
| 743 | leaf = bp2->data; | ||
| 744 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 745 | node->btree[0].hashval = leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval; | ||
| 746 | xfs_da_buf_done(bp2); | ||
| 747 | node->btree[0].before = cpu_to_be32(blkno); | ||
| 748 | node->hdr.count = cpu_to_be16(1); | ||
| 749 | xfs_da_log_buf(args->trans, bp1, | ||
| 750 | XFS_DA_LOGRANGE(node, &node->btree[0], sizeof(node->btree[0]))); | ||
| 751 | xfs_da_buf_done(bp1); | ||
| 752 | |||
| 753 | return retval; | ||
| 754 | } | ||
| 755 | |||
| 756 | |||
| 757 | /*======================================================================== | ||
| 758 | * Routines used for growing the Btree. | ||
| 759 | *========================================================================*/ | ||
| 760 | |||
| 761 | /* | ||
| 762 | * Create the initial contents of a leaf directory | ||
| 763 | * or a leaf in a node directory. | ||
| 764 | */ | ||
| 765 | STATIC int | ||
| 766 | xfs_dir_leaf_create(xfs_da_args_t *args, xfs_dablk_t blkno, xfs_dabuf_t **bpp) | ||
| 767 | { | ||
| 768 | xfs_dir_leafblock_t *leaf; | ||
| 769 | xfs_dir_leaf_hdr_t *hdr; | ||
| 770 | xfs_inode_t *dp; | ||
| 771 | xfs_dabuf_t *bp; | ||
| 772 | int retval; | ||
| 773 | |||
| 774 | dp = args->dp; | ||
| 775 | ASSERT(dp != NULL); | ||
| 776 | retval = xfs_da_get_buf(args->trans, dp, blkno, -1, &bp, XFS_DATA_FORK); | ||
| 777 | if (retval) | ||
| 778 | return retval; | ||
| 779 | ASSERT(bp != NULL); | ||
| 780 | leaf = bp->data; | ||
| 781 | memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); | ||
| 782 | hdr = &leaf->hdr; | ||
| 783 | hdr->info.magic = cpu_to_be16(XFS_DIR_LEAF_MAGIC); | ||
| 784 | hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount)); | ||
| 785 | if (!hdr->firstused) | ||
| 786 | hdr->firstused = cpu_to_be16(XFS_LBSIZE(dp->i_mount) - 1); | ||
| 787 | hdr->freemap[0].base = cpu_to_be16(sizeof(xfs_dir_leaf_hdr_t)); | ||
| 788 | hdr->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr->firstused) - | ||
| 789 | be16_to_cpu(hdr->freemap[0].base)); | ||
| 790 | |||
| 791 | xfs_da_log_buf(args->trans, bp, 0, XFS_LBSIZE(dp->i_mount) - 1); | ||
| 792 | |||
| 793 | *bpp = bp; | ||
| 794 | return 0; | ||
| 795 | } | ||
| 796 | |||
| 797 | /* | ||
| 798 | * Split the leaf node, rebalance, then add the new entry. | ||
| 799 | */ | ||
| 800 | int | ||
| 801 | xfs_dir_leaf_split(xfs_da_state_t *state, xfs_da_state_blk_t *oldblk, | ||
| 802 | xfs_da_state_blk_t *newblk) | ||
| 803 | { | ||
| 804 | xfs_dablk_t blkno; | ||
| 805 | xfs_da_args_t *args; | ||
| 806 | int error; | ||
| 807 | |||
| 808 | /* | ||
| 809 | * Allocate space for a new leaf node. | ||
| 810 | */ | ||
| 811 | args = state->args; | ||
| 812 | ASSERT(args != NULL); | ||
| 813 | ASSERT(oldblk->magic == XFS_DIR_LEAF_MAGIC); | ||
| 814 | error = xfs_da_grow_inode(args, &blkno); | ||
| 815 | if (error) | ||
| 816 | return error; | ||
| 817 | error = xfs_dir_leaf_create(args, blkno, &newblk->bp); | ||
| 818 | if (error) | ||
| 819 | return error; | ||
| 820 | newblk->blkno = blkno; | ||
| 821 | newblk->magic = XFS_DIR_LEAF_MAGIC; | ||
| 822 | |||
| 823 | /* | ||
| 824 | * Rebalance the entries across the two leaves. | ||
| 825 | */ | ||
| 826 | xfs_dir_leaf_rebalance(state, oldblk, newblk); | ||
| 827 | error = xfs_da_blk_link(state, oldblk, newblk); | ||
| 828 | if (error) | ||
| 829 | return error; | ||
| 830 | |||
| 831 | /* | ||
| 832 | * Insert the new entry in the correct block. | ||
| 833 | */ | ||
| 834 | if (state->inleaf) { | ||
| 835 | error = xfs_dir_leaf_add(oldblk->bp, args, oldblk->index); | ||
| 836 | } else { | ||
| 837 | error = xfs_dir_leaf_add(newblk->bp, args, newblk->index); | ||
| 838 | } | ||
| 839 | |||
| 840 | /* | ||
| 841 | * Update last hashval in each block since we added the name. | ||
| 842 | */ | ||
| 843 | oldblk->hashval = xfs_dir_leaf_lasthash(oldblk->bp, NULL); | ||
| 844 | newblk->hashval = xfs_dir_leaf_lasthash(newblk->bp, NULL); | ||
| 845 | return error; | ||
| 846 | } | ||
| 847 | |||
| 848 | /* | ||
| 849 | * Add a name to the leaf directory structure. | ||
| 850 | * | ||
| 851 | * Must take into account fragmented leaves and leaves where spacemap has | ||
| 852 | * lost some freespace information (ie: holes). | ||
| 853 | */ | ||
| 854 | int | ||
| 855 | xfs_dir_leaf_add(xfs_dabuf_t *bp, xfs_da_args_t *args, int index) | ||
| 856 | { | ||
| 857 | xfs_dir_leafblock_t *leaf; | ||
| 858 | xfs_dir_leaf_hdr_t *hdr; | ||
| 859 | xfs_dir_leaf_map_t *map; | ||
| 860 | int tablesize, entsize, sum, i, tmp, error; | ||
| 861 | |||
| 862 | leaf = bp->data; | ||
| 863 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 864 | ASSERT((index >= 0) && (index <= be16_to_cpu(leaf->hdr.count))); | ||
| 865 | hdr = &leaf->hdr; | ||
| 866 | entsize = XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen); | ||
| 867 | |||
| 868 | /* | ||
| 869 | * Search through freemap for first-fit on new name length. | ||
| 870 | * (may need to figure in size of entry struct too) | ||
| 871 | */ | ||
| 872 | tablesize = (be16_to_cpu(hdr->count) + 1) * | ||
| 873 | sizeof(xfs_dir_leaf_entry_t) + sizeof(xfs_dir_leaf_hdr_t); | ||
| 874 | map = &hdr->freemap[XFS_DIR_LEAF_MAPSIZE-1]; | ||
| 875 | for (sum = 0, i = XFS_DIR_LEAF_MAPSIZE-1; i >= 0; map--, i--) { | ||
| 876 | if (tablesize > be16_to_cpu(hdr->firstused)) { | ||
| 877 | sum += be16_to_cpu(map->size); | ||
| 878 | continue; | ||
| 879 | } | ||
| 880 | if (!map->size) | ||
| 881 | continue; /* no space in this map */ | ||
| 882 | tmp = entsize; | ||
| 883 | if (be16_to_cpu(map->base) < be16_to_cpu(hdr->firstused)) | ||
| 884 | tmp += (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 885 | if (be16_to_cpu(map->size) >= tmp) { | ||
| 886 | if (!args->justcheck) | ||
| 887 | xfs_dir_leaf_add_work(bp, args, index, i); | ||
| 888 | return 0; | ||
| 889 | } | ||
| 890 | sum += be16_to_cpu(map->size); | ||
| 891 | } | ||
| 892 | |||
| 893 | /* | ||
| 894 | * If there are no holes in the address space of the block, | ||
| 895 | * and we don't have enough freespace, then compaction will do us | ||
| 896 | * no good and we should just give up. | ||
| 897 | */ | ||
| 898 | if (!hdr->holes && (sum < entsize)) | ||
| 899 | return XFS_ERROR(ENOSPC); | ||
| 900 | |||
| 901 | /* | ||
| 902 | * Compact the entries to coalesce free space. | ||
| 903 | * Pass the justcheck flag so the checking pass can return | ||
| 904 | * an error, without changing anything, if it won't fit. | ||
| 905 | */ | ||
| 906 | error = xfs_dir_leaf_compact(args->trans, bp, | ||
| 907 | args->total == 0 ? | ||
| 908 | entsize + | ||
| 909 | (uint)sizeof(xfs_dir_leaf_entry_t) : 0, | ||
| 910 | args->justcheck); | ||
| 911 | if (error) | ||
| 912 | return error; | ||
| 913 | /* | ||
| 914 | * After compaction, the block is guaranteed to have only one | ||
| 915 | * free region, in freemap[0]. If it is not big enough, give up. | ||
| 916 | */ | ||
| 917 | if (be16_to_cpu(hdr->freemap[0].size) < | ||
| 918 | (entsize + (uint)sizeof(xfs_dir_leaf_entry_t))) | ||
| 919 | return XFS_ERROR(ENOSPC); | ||
| 920 | |||
| 921 | if (!args->justcheck) | ||
| 922 | xfs_dir_leaf_add_work(bp, args, index, 0); | ||
| 923 | return 0; | ||
| 924 | } | ||
| 925 | |||
| 926 | /* | ||
| 927 | * Add a name to a leaf directory structure. | ||
| 928 | */ | ||
| 929 | STATIC void | ||
| 930 | xfs_dir_leaf_add_work(xfs_dabuf_t *bp, xfs_da_args_t *args, int index, | ||
| 931 | int mapindex) | ||
| 932 | { | ||
| 933 | xfs_dir_leafblock_t *leaf; | ||
| 934 | xfs_dir_leaf_hdr_t *hdr; | ||
| 935 | xfs_dir_leaf_entry_t *entry; | ||
| 936 | xfs_dir_leaf_name_t *namest; | ||
| 937 | xfs_dir_leaf_map_t *map; | ||
| 938 | /* REFERENCED */ | ||
| 939 | xfs_mount_t *mp; | ||
| 940 | int tmp, i; | ||
| 941 | |||
| 942 | leaf = bp->data; | ||
| 943 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 944 | hdr = &leaf->hdr; | ||
| 945 | ASSERT((mapindex >= 0) && (mapindex < XFS_DIR_LEAF_MAPSIZE)); | ||
| 946 | ASSERT((index >= 0) && (index <= be16_to_cpu(hdr->count))); | ||
| 947 | |||
| 948 | /* | ||
| 949 | * Force open some space in the entry array and fill it in. | ||
| 950 | */ | ||
| 951 | entry = &leaf->entries[index]; | ||
| 952 | if (index < be16_to_cpu(hdr->count)) { | ||
| 953 | tmp = be16_to_cpu(hdr->count) - index; | ||
| 954 | tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 955 | memmove(entry + 1, entry, tmp); | ||
| 956 | xfs_da_log_buf(args->trans, bp, | ||
| 957 | XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry))); | ||
| 958 | } | ||
| 959 | be16_add(&hdr->count, 1); | ||
| 960 | |||
| 961 | /* | ||
| 962 | * Allocate space for the new string (at the end of the run). | ||
| 963 | */ | ||
| 964 | map = &hdr->freemap[mapindex]; | ||
| 965 | mp = args->trans->t_mountp; | ||
| 966 | ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); | ||
| 967 | ASSERT(be16_to_cpu(map->size) >= XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen)); | ||
| 968 | ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); | ||
| 969 | |||
| 970 | be16_add(&map->size, -(XFS_DIR_LEAF_ENTSIZE_BYNAME(args->namelen))); | ||
| 971 | entry->nameidx = cpu_to_be16(be16_to_cpu(map->base) + | ||
| 972 | be16_to_cpu(map->size)); | ||
| 973 | entry->hashval = cpu_to_be32(args->hashval); | ||
| 974 | entry->namelen = args->namelen; | ||
| 975 | xfs_da_log_buf(args->trans, bp, | ||
| 976 | XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry))); | ||
| 977 | |||
| 978 | /* | ||
| 979 | * Copy the string and inode number into the new space. | ||
| 980 | */ | ||
| 981 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); | ||
| 982 | XFS_DIR_SF_PUT_DIRINO(&args->inumber, &namest->inumber); | ||
| 983 | memcpy(namest->name, args->name, args->namelen); | ||
| 984 | xfs_da_log_buf(args->trans, bp, | ||
| 985 | XFS_DA_LOGRANGE(leaf, namest, XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry))); | ||
| 986 | |||
| 987 | /* | ||
| 988 | * Update the control info for this leaf node | ||
| 989 | */ | ||
| 990 | if (be16_to_cpu(entry->nameidx) < be16_to_cpu(hdr->firstused)) | ||
| 991 | hdr->firstused = entry->nameidx; | ||
| 992 | ASSERT(be16_to_cpu(hdr->firstused) >= | ||
| 993 | ((be16_to_cpu(hdr->count)*sizeof(*entry))+sizeof(*hdr))); | ||
| 994 | tmp = (be16_to_cpu(hdr->count)-1) * (uint)sizeof(xfs_dir_leaf_entry_t) | ||
| 995 | + (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
| 996 | map = &hdr->freemap[0]; | ||
| 997 | for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) { | ||
| 998 | if (be16_to_cpu(map->base) == tmp) { | ||
| 999 | int entry_size = sizeof(xfs_dir_leaf_entry_t); | ||
| 1000 | be16_add(&map->base, entry_size); | ||
| 1001 | be16_add(&map->size, -entry_size); | ||
| 1002 | } | ||
| 1003 | } | ||
| 1004 | be16_add(&hdr->namebytes, args->namelen); | ||
| 1005 | xfs_da_log_buf(args->trans, bp, | ||
| 1006 | XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | /* | ||
| 1010 | * Garbage collect a leaf directory block by copying it to a new buffer. | ||
| 1011 | */ | ||
| 1012 | STATIC int | ||
| 1013 | xfs_dir_leaf_compact(xfs_trans_t *trans, xfs_dabuf_t *bp, int musthave, | ||
| 1014 | int justcheck) | ||
| 1015 | { | ||
| 1016 | xfs_dir_leafblock_t *leaf_s, *leaf_d; | ||
| 1017 | xfs_dir_leaf_hdr_t *hdr_s, *hdr_d; | ||
| 1018 | xfs_mount_t *mp; | ||
| 1019 | char *tmpbuffer; | ||
| 1020 | char *tmpbuffer2=NULL; | ||
| 1021 | int rval; | ||
| 1022 | int lbsize; | ||
| 1023 | |||
| 1024 | mp = trans->t_mountp; | ||
| 1025 | lbsize = XFS_LBSIZE(mp); | ||
| 1026 | tmpbuffer = kmem_alloc(lbsize, KM_SLEEP); | ||
| 1027 | ASSERT(tmpbuffer != NULL); | ||
| 1028 | memcpy(tmpbuffer, bp->data, lbsize); | ||
| 1029 | |||
| 1030 | /* | ||
| 1031 | * Make a second copy in case xfs_dir_leaf_moveents() | ||
| 1032 | * below destroys the original. | ||
| 1033 | */ | ||
| 1034 | if (musthave || justcheck) { | ||
| 1035 | tmpbuffer2 = kmem_alloc(lbsize, KM_SLEEP); | ||
| 1036 | memcpy(tmpbuffer2, bp->data, lbsize); | ||
| 1037 | } | ||
| 1038 | memset(bp->data, 0, lbsize); | ||
| 1039 | |||
| 1040 | /* | ||
| 1041 | * Copy basic information | ||
| 1042 | */ | ||
| 1043 | leaf_s = (xfs_dir_leafblock_t *)tmpbuffer; | ||
| 1044 | leaf_d = bp->data; | ||
| 1045 | hdr_s = &leaf_s->hdr; | ||
| 1046 | hdr_d = &leaf_d->hdr; | ||
| 1047 | hdr_d->info = hdr_s->info; /* struct copy */ | ||
| 1048 | hdr_d->firstused = cpu_to_be16(lbsize); | ||
| 1049 | if (!hdr_d->firstused) | ||
| 1050 | hdr_d->firstused = cpu_to_be16(lbsize - 1); | ||
| 1051 | hdr_d->namebytes = 0; | ||
| 1052 | hdr_d->count = 0; | ||
| 1053 | hdr_d->holes = 0; | ||
| 1054 | hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_dir_leaf_hdr_t)); | ||
| 1055 | hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - | ||
| 1056 | be16_to_cpu(hdr_d->freemap[0].base)); | ||
| 1057 | |||
| 1058 | /* | ||
| 1059 | * Copy all entry's in the same (sorted) order, | ||
| 1060 | * but allocate filenames packed and in sequence. | ||
| 1061 | * This changes the source (leaf_s) as well. | ||
| 1062 | */ | ||
| 1063 | xfs_dir_leaf_moveents(leaf_s, 0, leaf_d, 0, be16_to_cpu(hdr_s->count), mp); | ||
| 1064 | |||
| 1065 | if (musthave && be16_to_cpu(hdr_d->freemap[0].size) < musthave) | ||
| 1066 | rval = XFS_ERROR(ENOSPC); | ||
| 1067 | else | ||
| 1068 | rval = 0; | ||
| 1069 | |||
| 1070 | if (justcheck || rval == ENOSPC) { | ||
| 1071 | ASSERT(tmpbuffer2); | ||
| 1072 | memcpy(bp->data, tmpbuffer2, lbsize); | ||
| 1073 | } else { | ||
| 1074 | xfs_da_log_buf(trans, bp, 0, lbsize - 1); | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | kmem_free(tmpbuffer, lbsize); | ||
| 1078 | if (musthave || justcheck) | ||
| 1079 | kmem_free(tmpbuffer2, lbsize); | ||
| 1080 | return rval; | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | /* | ||
| 1084 | * Redistribute the directory entries between two leaf nodes, | ||
| 1085 | * taking into account the size of the new entry. | ||
| 1086 | * | ||
| 1087 | * NOTE: if new block is empty, then it will get the upper half of old block. | ||
| 1088 | */ | ||
| 1089 | STATIC void | ||
| 1090 | xfs_dir_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, | ||
| 1091 | xfs_da_state_blk_t *blk2) | ||
| 1092 | { | ||
| 1093 | xfs_da_state_blk_t *tmp_blk; | ||
| 1094 | xfs_dir_leafblock_t *leaf1, *leaf2; | ||
| 1095 | xfs_dir_leaf_hdr_t *hdr1, *hdr2; | ||
| 1096 | int count, totallen, max, space, swap; | ||
| 1097 | |||
| 1098 | /* | ||
| 1099 | * Set up environment. | ||
| 1100 | */ | ||
| 1101 | ASSERT(blk1->magic == XFS_DIR_LEAF_MAGIC); | ||
| 1102 | ASSERT(blk2->magic == XFS_DIR_LEAF_MAGIC); | ||
| 1103 | leaf1 = blk1->bp->data; | ||
| 1104 | leaf2 = blk2->bp->data; | ||
| 1105 | ASSERT(be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1106 | ASSERT(be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1107 | |||
| 1108 | /* | ||
| 1109 | * Check ordering of blocks, reverse if it makes things simpler. | ||
| 1110 | */ | ||
| 1111 | swap = 0; | ||
| 1112 | if (xfs_dir_leaf_order(blk1->bp, blk2->bp)) { | ||
| 1113 | tmp_blk = blk1; | ||
| 1114 | blk1 = blk2; | ||
| 1115 | blk2 = tmp_blk; | ||
| 1116 | leaf1 = blk1->bp->data; | ||
| 1117 | leaf2 = blk2->bp->data; | ||
| 1118 | swap = 1; | ||
| 1119 | } | ||
| 1120 | hdr1 = &leaf1->hdr; | ||
| 1121 | hdr2 = &leaf2->hdr; | ||
| 1122 | |||
| 1123 | /* | ||
| 1124 | * Examine entries until we reduce the absolute difference in | ||
| 1125 | * byte usage between the two blocks to a minimum. Then get | ||
| 1126 | * the direction to copy and the number of elements to move. | ||
| 1127 | */ | ||
| 1128 | state->inleaf = xfs_dir_leaf_figure_balance(state, blk1, blk2, | ||
| 1129 | &count, &totallen); | ||
| 1130 | if (swap) | ||
| 1131 | state->inleaf = !state->inleaf; | ||
| 1132 | |||
| 1133 | /* | ||
| 1134 | * Move any entries required from leaf to leaf: | ||
| 1135 | */ | ||
| 1136 | if (count < be16_to_cpu(hdr1->count)) { | ||
| 1137 | /* | ||
| 1138 | * Figure the total bytes to be added to the destination leaf. | ||
| 1139 | */ | ||
| 1140 | count = be16_to_cpu(hdr1->count) - count; /* number entries being moved */ | ||
| 1141 | space = be16_to_cpu(hdr1->namebytes) - totallen; | ||
| 1142 | space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1); | ||
| 1143 | space += count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1144 | |||
| 1145 | /* | ||
| 1146 | * leaf2 is the destination, compact it if it looks tight. | ||
| 1147 | */ | ||
| 1148 | max = be16_to_cpu(hdr2->firstused) - (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
| 1149 | max -= be16_to_cpu(hdr2->count) * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1150 | if (space > max) { | ||
| 1151 | xfs_dir_leaf_compact(state->args->trans, blk2->bp, | ||
| 1152 | 0, 0); | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | /* | ||
| 1156 | * Move high entries from leaf1 to low end of leaf2. | ||
| 1157 | */ | ||
| 1158 | xfs_dir_leaf_moveents(leaf1, be16_to_cpu(hdr1->count) - count, | ||
| 1159 | leaf2, 0, count, state->mp); | ||
| 1160 | |||
| 1161 | xfs_da_log_buf(state->args->trans, blk1->bp, 0, | ||
| 1162 | state->blocksize-1); | ||
| 1163 | xfs_da_log_buf(state->args->trans, blk2->bp, 0, | ||
| 1164 | state->blocksize-1); | ||
| 1165 | |||
| 1166 | } else if (count > be16_to_cpu(hdr1->count)) { | ||
| 1167 | /* | ||
| 1168 | * Figure the total bytes to be added to the destination leaf. | ||
| 1169 | */ | ||
| 1170 | count -= be16_to_cpu(hdr1->count); /* number entries being moved */ | ||
| 1171 | space = totallen - be16_to_cpu(hdr1->namebytes); | ||
| 1172 | space += count * ((uint)sizeof(xfs_dir_leaf_name_t)-1); | ||
| 1173 | space += count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1174 | |||
| 1175 | /* | ||
| 1176 | * leaf1 is the destination, compact it if it looks tight. | ||
| 1177 | */ | ||
| 1178 | max = be16_to_cpu(hdr1->firstused) - (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
| 1179 | max -= be16_to_cpu(hdr1->count) * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1180 | if (space > max) { | ||
| 1181 | xfs_dir_leaf_compact(state->args->trans, blk1->bp, | ||
| 1182 | 0, 0); | ||
| 1183 | } | ||
| 1184 | |||
| 1185 | /* | ||
| 1186 | * Move low entries from leaf2 to high end of leaf1. | ||
| 1187 | */ | ||
| 1188 | xfs_dir_leaf_moveents(leaf2, 0, leaf1, be16_to_cpu(hdr1->count), | ||
| 1189 | count, state->mp); | ||
| 1190 | |||
| 1191 | xfs_da_log_buf(state->args->trans, blk1->bp, 0, | ||
| 1192 | state->blocksize-1); | ||
| 1193 | xfs_da_log_buf(state->args->trans, blk2->bp, 0, | ||
| 1194 | state->blocksize-1); | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | /* | ||
| 1198 | * Copy out last hashval in each block for B-tree code. | ||
| 1199 | */ | ||
| 1200 | blk1->hashval = be32_to_cpu(leaf1->entries[ | ||
| 1201 | be16_to_cpu(leaf1->hdr.count)-1].hashval); | ||
| 1202 | blk2->hashval = be32_to_cpu(leaf2->entries[ | ||
| 1203 | be16_to_cpu(leaf2->hdr.count)-1].hashval); | ||
| 1204 | |||
| 1205 | /* | ||
| 1206 | * Adjust the expected index for insertion. | ||
| 1207 | * GROT: this doesn't work unless blk2 was originally empty. | ||
| 1208 | */ | ||
| 1209 | if (!state->inleaf) { | ||
| 1210 | blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); | ||
| 1211 | } | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | /* | ||
| 1215 | * Examine entries until we reduce the absolute difference in | ||
| 1216 | * byte usage between the two blocks to a minimum. | ||
| 1217 | * GROT: Is this really necessary? With other than a 512 byte blocksize, | ||
| 1218 | * GROT: there will always be enough room in either block for a new entry. | ||
| 1219 | * GROT: Do a double-split for this case? | ||
| 1220 | */ | ||
| 1221 | STATIC int | ||
| 1222 | xfs_dir_leaf_figure_balance(xfs_da_state_t *state, | ||
| 1223 | xfs_da_state_blk_t *blk1, | ||
| 1224 | xfs_da_state_blk_t *blk2, | ||
| 1225 | int *countarg, int *namebytesarg) | ||
| 1226 | { | ||
| 1227 | xfs_dir_leafblock_t *leaf1, *leaf2; | ||
| 1228 | xfs_dir_leaf_hdr_t *hdr1, *hdr2; | ||
| 1229 | xfs_dir_leaf_entry_t *entry; | ||
| 1230 | int count, max, totallen, half; | ||
| 1231 | int lastdelta, foundit, tmp; | ||
| 1232 | |||
| 1233 | /* | ||
| 1234 | * Set up environment. | ||
| 1235 | */ | ||
| 1236 | leaf1 = blk1->bp->data; | ||
| 1237 | leaf2 = blk2->bp->data; | ||
| 1238 | hdr1 = &leaf1->hdr; | ||
| 1239 | hdr2 = &leaf2->hdr; | ||
| 1240 | foundit = 0; | ||
| 1241 | totallen = 0; | ||
| 1242 | |||
| 1243 | /* | ||
| 1244 | * Examine entries until we reduce the absolute difference in | ||
| 1245 | * byte usage between the two blocks to a minimum. | ||
| 1246 | */ | ||
| 1247 | max = be16_to_cpu(hdr1->count) + be16_to_cpu(hdr2->count); | ||
| 1248 | half = (max+1) * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1); | ||
| 1249 | half += be16_to_cpu(hdr1->namebytes) + be16_to_cpu(hdr2->namebytes) + | ||
| 1250 | state->args->namelen; | ||
| 1251 | half /= 2; | ||
| 1252 | lastdelta = state->blocksize; | ||
| 1253 | entry = &leaf1->entries[0]; | ||
| 1254 | for (count = 0; count < max; entry++, count++) { | ||
| 1255 | |||
| 1256 | #define XFS_DIR_ABS(A) (((A) < 0) ? -(A) : (A)) | ||
| 1257 | /* | ||
| 1258 | * The new entry is in the first block, account for it. | ||
| 1259 | */ | ||
| 1260 | if (count == blk1->index) { | ||
| 1261 | tmp = totallen + (uint)sizeof(*entry) | ||
| 1262 | + XFS_DIR_LEAF_ENTSIZE_BYNAME(state->args->namelen); | ||
| 1263 | if (XFS_DIR_ABS(half - tmp) > lastdelta) | ||
| 1264 | break; | ||
| 1265 | lastdelta = XFS_DIR_ABS(half - tmp); | ||
| 1266 | totallen = tmp; | ||
| 1267 | foundit = 1; | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | /* | ||
| 1271 | * Wrap around into the second block if necessary. | ||
| 1272 | */ | ||
| 1273 | if (count == be16_to_cpu(hdr1->count)) { | ||
| 1274 | leaf1 = leaf2; | ||
| 1275 | entry = &leaf1->entries[0]; | ||
| 1276 | } | ||
| 1277 | |||
| 1278 | /* | ||
| 1279 | * Figure out if next leaf entry would be too much. | ||
| 1280 | */ | ||
| 1281 | tmp = totallen + (uint)sizeof(*entry) | ||
| 1282 | + XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry); | ||
| 1283 | if (XFS_DIR_ABS(half - tmp) > lastdelta) | ||
| 1284 | break; | ||
| 1285 | lastdelta = XFS_DIR_ABS(half - tmp); | ||
| 1286 | totallen = tmp; | ||
| 1287 | #undef XFS_DIR_ABS | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | /* | ||
| 1291 | * Calculate the number of namebytes that will end up in lower block. | ||
| 1292 | * If new entry not in lower block, fix up the count. | ||
| 1293 | */ | ||
| 1294 | totallen -= | ||
| 1295 | count * (uint)(sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1); | ||
| 1296 | if (foundit) { | ||
| 1297 | totallen -= (sizeof(*entry)+sizeof(xfs_dir_leaf_entry_t)-1) + | ||
| 1298 | state->args->namelen; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | *countarg = count; | ||
| 1302 | *namebytesarg = totallen; | ||
| 1303 | return foundit; | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | /*======================================================================== | ||
| 1307 | * Routines used for shrinking the Btree. | ||
| 1308 | *========================================================================*/ | ||
| 1309 | |||
| 1310 | /* | ||
| 1311 | * Check a leaf block and its neighbors to see if the block should be | ||
| 1312 | * collapsed into one or the other neighbor. Always keep the block | ||
| 1313 | * with the smaller block number. | ||
| 1314 | * If the current block is over 50% full, don't try to join it, return 0. | ||
| 1315 | * If the block is empty, fill in the state structure and return 2. | ||
| 1316 | * If it can be collapsed, fill in the state structure and return 1. | ||
| 1317 | * If nothing can be done, return 0. | ||
| 1318 | */ | ||
| 1319 | int | ||
| 1320 | xfs_dir_leaf_toosmall(xfs_da_state_t *state, int *action) | ||
| 1321 | { | ||
| 1322 | xfs_dir_leafblock_t *leaf; | ||
| 1323 | xfs_da_state_blk_t *blk; | ||
| 1324 | xfs_da_blkinfo_t *info; | ||
| 1325 | int count, bytes, forward, error, retval, i; | ||
| 1326 | xfs_dablk_t blkno; | ||
| 1327 | xfs_dabuf_t *bp; | ||
| 1328 | |||
| 1329 | /* | ||
| 1330 | * Check for the degenerate case of the block being over 50% full. | ||
| 1331 | * If so, it's not worth even looking to see if we might be able | ||
| 1332 | * to coalesce with a sibling. | ||
| 1333 | */ | ||
| 1334 | blk = &state->path.blk[ state->path.active-1 ]; | ||
| 1335 | info = blk->bp->data; | ||
| 1336 | ASSERT(be16_to_cpu(info->magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1337 | leaf = (xfs_dir_leafblock_t *)info; | ||
| 1338 | count = be16_to_cpu(leaf->hdr.count); | ||
| 1339 | bytes = (uint)sizeof(xfs_dir_leaf_hdr_t) + | ||
| 1340 | count * (uint)sizeof(xfs_dir_leaf_entry_t) + | ||
| 1341 | count * ((uint)sizeof(xfs_dir_leaf_name_t)-1) + | ||
| 1342 | be16_to_cpu(leaf->hdr.namebytes); | ||
| 1343 | if (bytes > (state->blocksize >> 1)) { | ||
| 1344 | *action = 0; /* blk over 50%, don't try to join */ | ||
| 1345 | return 0; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | /* | ||
| 1349 | * Check for the degenerate case of the block being empty. | ||
| 1350 | * If the block is empty, we'll simply delete it, no need to | ||
| 1351 | * coalesce it with a sibling block. We choose (arbitrarily) | ||
| 1352 | * to merge with the forward block unless it is NULL. | ||
| 1353 | */ | ||
| 1354 | if (count == 0) { | ||
| 1355 | /* | ||
| 1356 | * Make altpath point to the block we want to keep and | ||
| 1357 | * path point to the block we want to drop (this one). | ||
| 1358 | */ | ||
| 1359 | forward = (info->forw != 0); | ||
| 1360 | memcpy(&state->altpath, &state->path, sizeof(state->path)); | ||
| 1361 | error = xfs_da_path_shift(state, &state->altpath, forward, | ||
| 1362 | 0, &retval); | ||
| 1363 | if (error) | ||
| 1364 | return error; | ||
| 1365 | if (retval) { | ||
| 1366 | *action = 0; | ||
| 1367 | } else { | ||
| 1368 | *action = 2; | ||
| 1369 | } | ||
| 1370 | return 0; | ||
| 1371 | } | ||
| 1372 | |||
| 1373 | /* | ||
| 1374 | * Examine each sibling block to see if we can coalesce with | ||
| 1375 | * at least 25% free space to spare. We need to figure out | ||
| 1376 | * whether to merge with the forward or the backward block. | ||
| 1377 | * We prefer coalescing with the lower numbered sibling so as | ||
| 1378 | * to shrink a directory over time. | ||
| 1379 | */ | ||
| 1380 | forward = (be32_to_cpu(info->forw) < be32_to_cpu(info->back)); /* start with smaller blk num */ | ||
| 1381 | for (i = 0; i < 2; forward = !forward, i++) { | ||
| 1382 | if (forward) | ||
| 1383 | blkno = be32_to_cpu(info->forw); | ||
| 1384 | else | ||
| 1385 | blkno = be32_to_cpu(info->back); | ||
| 1386 | if (blkno == 0) | ||
| 1387 | continue; | ||
| 1388 | error = xfs_da_read_buf(state->args->trans, state->args->dp, | ||
| 1389 | blkno, -1, &bp, | ||
| 1390 | XFS_DATA_FORK); | ||
| 1391 | if (error) | ||
| 1392 | return error; | ||
| 1393 | ASSERT(bp != NULL); | ||
| 1394 | |||
| 1395 | leaf = (xfs_dir_leafblock_t *)info; | ||
| 1396 | count = be16_to_cpu(leaf->hdr.count); | ||
| 1397 | bytes = state->blocksize - (state->blocksize>>2); | ||
| 1398 | bytes -= be16_to_cpu(leaf->hdr.namebytes); | ||
| 1399 | leaf = bp->data; | ||
| 1400 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1401 | count += be16_to_cpu(leaf->hdr.count); | ||
| 1402 | bytes -= be16_to_cpu(leaf->hdr.namebytes); | ||
| 1403 | bytes -= count * ((uint)sizeof(xfs_dir_leaf_name_t) - 1); | ||
| 1404 | bytes -= count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1405 | bytes -= (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
| 1406 | if (bytes >= 0) | ||
| 1407 | break; /* fits with at least 25% to spare */ | ||
| 1408 | |||
| 1409 | xfs_da_brelse(state->args->trans, bp); | ||
| 1410 | } | ||
| 1411 | if (i >= 2) { | ||
| 1412 | *action = 0; | ||
| 1413 | return 0; | ||
| 1414 | } | ||
| 1415 | xfs_da_buf_done(bp); | ||
| 1416 | |||
| 1417 | /* | ||
| 1418 | * Make altpath point to the block we want to keep (the lower | ||
| 1419 | * numbered block) and path point to the block we want to drop. | ||
| 1420 | */ | ||
| 1421 | memcpy(&state->altpath, &state->path, sizeof(state->path)); | ||
| 1422 | if (blkno < blk->blkno) { | ||
| 1423 | error = xfs_da_path_shift(state, &state->altpath, forward, | ||
| 1424 | 0, &retval); | ||
| 1425 | } else { | ||
| 1426 | error = xfs_da_path_shift(state, &state->path, forward, | ||
| 1427 | 0, &retval); | ||
| 1428 | } | ||
| 1429 | if (error) | ||
| 1430 | return error; | ||
| 1431 | if (retval) { | ||
| 1432 | *action = 0; | ||
| 1433 | } else { | ||
| 1434 | *action = 1; | ||
| 1435 | } | ||
| 1436 | return 0; | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | /* | ||
| 1440 | * Remove a name from the leaf directory structure. | ||
| 1441 | * | ||
| 1442 | * Return 1 if leaf is less than 37% full, 0 if >= 37% full. | ||
| 1443 | * If two leaves are 37% full, when combined they will leave 25% free. | ||
| 1444 | */ | ||
| 1445 | int | ||
| 1446 | xfs_dir_leaf_remove(xfs_trans_t *trans, xfs_dabuf_t *bp, int index) | ||
| 1447 | { | ||
| 1448 | xfs_dir_leafblock_t *leaf; | ||
| 1449 | xfs_dir_leaf_hdr_t *hdr; | ||
| 1450 | xfs_dir_leaf_map_t *map; | ||
| 1451 | xfs_dir_leaf_entry_t *entry; | ||
| 1452 | xfs_dir_leaf_name_t *namest; | ||
| 1453 | int before, after, smallest, entsize; | ||
| 1454 | int tablesize, tmp, i; | ||
| 1455 | xfs_mount_t *mp; | ||
| 1456 | |||
| 1457 | leaf = bp->data; | ||
| 1458 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1459 | hdr = &leaf->hdr; | ||
| 1460 | mp = trans->t_mountp; | ||
| 1461 | ASSERT(hdr->count && (be16_to_cpu(hdr->count) < (XFS_LBSIZE(mp)/8))); | ||
| 1462 | ASSERT((index >= 0) && (index < be16_to_cpu(hdr->count))); | ||
| 1463 | ASSERT(be16_to_cpu(hdr->firstused) >= | ||
| 1464 | ((be16_to_cpu(hdr->count)*sizeof(*entry))+sizeof(*hdr))); | ||
| 1465 | entry = &leaf->entries[index]; | ||
| 1466 | ASSERT(be16_to_cpu(entry->nameidx) >= be16_to_cpu(hdr->firstused)); | ||
| 1467 | ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); | ||
| 1468 | |||
| 1469 | /* | ||
| 1470 | * Scan through free region table: | ||
| 1471 | * check for adjacency of free'd entry with an existing one, | ||
| 1472 | * find smallest free region in case we need to replace it, | ||
| 1473 | * adjust any map that borders the entry table, | ||
| 1474 | */ | ||
| 1475 | tablesize = be16_to_cpu(hdr->count) * (uint)sizeof(xfs_dir_leaf_entry_t) | ||
| 1476 | + (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
| 1477 | map = &hdr->freemap[0]; | ||
| 1478 | tmp = be16_to_cpu(map->size); | ||
| 1479 | before = after = -1; | ||
| 1480 | smallest = XFS_DIR_LEAF_MAPSIZE - 1; | ||
| 1481 | entsize = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry); | ||
| 1482 | for (i = 0; i < XFS_DIR_LEAF_MAPSIZE; map++, i++) { | ||
| 1483 | ASSERT(be16_to_cpu(map->base) < XFS_LBSIZE(mp)); | ||
| 1484 | ASSERT(be16_to_cpu(map->size) < XFS_LBSIZE(mp)); | ||
| 1485 | if (be16_to_cpu(map->base) == tablesize) { | ||
| 1486 | int entry_size = sizeof(xfs_dir_leaf_entry_t); | ||
| 1487 | be16_add(&map->base, -entry_size); | ||
| 1488 | be16_add(&map->size, entry_size); | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | if ((be16_to_cpu(map->base) + be16_to_cpu(map->size)) == | ||
| 1492 | be16_to_cpu(entry->nameidx)) { | ||
| 1493 | before = i; | ||
| 1494 | } else if (be16_to_cpu(map->base) == | ||
| 1495 | (be16_to_cpu(entry->nameidx) + entsize)) { | ||
| 1496 | after = i; | ||
| 1497 | } else if (be16_to_cpu(map->size) < tmp) { | ||
| 1498 | tmp = be16_to_cpu(map->size); | ||
| 1499 | smallest = i; | ||
| 1500 | } | ||
| 1501 | } | ||
| 1502 | |||
| 1503 | /* | ||
| 1504 | * Coalesce adjacent freemap regions, | ||
| 1505 | * or replace the smallest region. | ||
| 1506 | */ | ||
| 1507 | if ((before >= 0) || (after >= 0)) { | ||
| 1508 | if ((before >= 0) && (after >= 0)) { | ||
| 1509 | map = &hdr->freemap[before]; | ||
| 1510 | be16_add(&map->size, entsize); | ||
| 1511 | be16_add(&map->size, be16_to_cpu(hdr->freemap[after].size)); | ||
| 1512 | hdr->freemap[after].base = 0; | ||
| 1513 | hdr->freemap[after].size = 0; | ||
| 1514 | } else if (before >= 0) { | ||
| 1515 | map = &hdr->freemap[before]; | ||
| 1516 | be16_add(&map->size, entsize); | ||
| 1517 | } else { | ||
| 1518 | map = &hdr->freemap[after]; | ||
| 1519 | map->base = entry->nameidx; | ||
| 1520 | be16_add(&map->size, entsize); | ||
| 1521 | } | ||
| 1522 | } else { | ||
| 1523 | /* | ||
| 1524 | * Replace smallest region (if it is smaller than free'd entry) | ||
| 1525 | */ | ||
| 1526 | map = &hdr->freemap[smallest]; | ||
| 1527 | if (be16_to_cpu(map->size) < entsize) { | ||
| 1528 | map->base = entry->nameidx; | ||
| 1529 | map->size = cpu_to_be16(entsize); | ||
| 1530 | } | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | /* | ||
| 1534 | * Did we remove the first entry? | ||
| 1535 | */ | ||
| 1536 | if (be16_to_cpu(entry->nameidx) == be16_to_cpu(hdr->firstused)) | ||
| 1537 | smallest = 1; | ||
| 1538 | else | ||
| 1539 | smallest = 0; | ||
| 1540 | |||
| 1541 | /* | ||
| 1542 | * Compress the remaining entries and zero out the removed stuff. | ||
| 1543 | */ | ||
| 1544 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); | ||
| 1545 | memset((char *)namest, 0, entsize); | ||
| 1546 | xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, namest, entsize)); | ||
| 1547 | |||
| 1548 | be16_add(&hdr->namebytes, -(entry->namelen)); | ||
| 1549 | tmp = (be16_to_cpu(hdr->count) - index) * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1550 | memmove(entry, entry + 1, tmp); | ||
| 1551 | be16_add(&hdr->count, -1); | ||
| 1552 | xfs_da_log_buf(trans, bp, | ||
| 1553 | XFS_DA_LOGRANGE(leaf, entry, tmp + (uint)sizeof(*entry))); | ||
| 1554 | entry = &leaf->entries[be16_to_cpu(hdr->count)]; | ||
| 1555 | memset((char *)entry, 0, sizeof(xfs_dir_leaf_entry_t)); | ||
| 1556 | |||
| 1557 | /* | ||
| 1558 | * If we removed the first entry, re-find the first used byte | ||
| 1559 | * in the name area. Note that if the entry was the "firstused", | ||
| 1560 | * then we don't have a "hole" in our block resulting from | ||
| 1561 | * removing the name. | ||
| 1562 | */ | ||
| 1563 | if (smallest) { | ||
| 1564 | tmp = XFS_LBSIZE(mp); | ||
| 1565 | entry = &leaf->entries[0]; | ||
| 1566 | for (i = be16_to_cpu(hdr->count)-1; i >= 0; entry++, i--) { | ||
| 1567 | ASSERT(be16_to_cpu(entry->nameidx) >= | ||
| 1568 | be16_to_cpu(hdr->firstused)); | ||
| 1569 | ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); | ||
| 1570 | if (be16_to_cpu(entry->nameidx) < tmp) | ||
| 1571 | tmp = be16_to_cpu(entry->nameidx); | ||
| 1572 | } | ||
| 1573 | hdr->firstused = cpu_to_be16(tmp); | ||
| 1574 | if (!hdr->firstused) | ||
| 1575 | hdr->firstused = cpu_to_be16(tmp - 1); | ||
| 1576 | } else { | ||
| 1577 | hdr->holes = 1; /* mark as needing compaction */ | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | xfs_da_log_buf(trans, bp, XFS_DA_LOGRANGE(leaf, hdr, sizeof(*hdr))); | ||
| 1581 | |||
| 1582 | /* | ||
| 1583 | * Check if leaf is less than 50% full, caller may want to | ||
| 1584 | * "join" the leaf with a sibling if so. | ||
| 1585 | */ | ||
| 1586 | tmp = (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
| 1587 | tmp += be16_to_cpu(leaf->hdr.count) * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1588 | tmp += be16_to_cpu(leaf->hdr.count) * ((uint)sizeof(xfs_dir_leaf_name_t) - 1); | ||
| 1589 | tmp += be16_to_cpu(leaf->hdr.namebytes); | ||
| 1590 | if (tmp < mp->m_dir_magicpct) | ||
| 1591 | return 1; /* leaf is < 37% full */ | ||
| 1592 | return 0; | ||
| 1593 | } | ||
| 1594 | |||
| 1595 | /* | ||
| 1596 | * Move all the directory entries from drop_leaf into save_leaf. | ||
| 1597 | */ | ||
| 1598 | void | ||
| 1599 | xfs_dir_leaf_unbalance(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | ||
| 1600 | xfs_da_state_blk_t *save_blk) | ||
| 1601 | { | ||
| 1602 | xfs_dir_leafblock_t *drop_leaf, *save_leaf, *tmp_leaf; | ||
| 1603 | xfs_dir_leaf_hdr_t *drop_hdr, *save_hdr, *tmp_hdr; | ||
| 1604 | xfs_mount_t *mp; | ||
| 1605 | char *tmpbuffer; | ||
| 1606 | |||
| 1607 | /* | ||
| 1608 | * Set up environment. | ||
| 1609 | */ | ||
| 1610 | mp = state->mp; | ||
| 1611 | ASSERT(drop_blk->magic == XFS_DIR_LEAF_MAGIC); | ||
| 1612 | ASSERT(save_blk->magic == XFS_DIR_LEAF_MAGIC); | ||
| 1613 | drop_leaf = drop_blk->bp->data; | ||
| 1614 | save_leaf = save_blk->bp->data; | ||
| 1615 | ASSERT(be16_to_cpu(drop_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1616 | ASSERT(be16_to_cpu(save_leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1617 | drop_hdr = &drop_leaf->hdr; | ||
| 1618 | save_hdr = &save_leaf->hdr; | ||
| 1619 | |||
| 1620 | /* | ||
| 1621 | * Save last hashval from dying block for later Btree fixup. | ||
| 1622 | */ | ||
| 1623 | drop_blk->hashval = be32_to_cpu(drop_leaf->entries[ | ||
| 1624 | be16_to_cpu(drop_leaf->hdr.count)-1].hashval); | ||
| 1625 | |||
| 1626 | /* | ||
| 1627 | * Check if we need a temp buffer, or can we do it in place. | ||
| 1628 | * Note that we don't check "leaf" for holes because we will | ||
| 1629 | * always be dropping it, toosmall() decided that for us already. | ||
| 1630 | */ | ||
| 1631 | if (save_hdr->holes == 0) { | ||
| 1632 | /* | ||
| 1633 | * dest leaf has no holes, so we add there. May need | ||
| 1634 | * to make some room in the entry array. | ||
| 1635 | */ | ||
| 1636 | if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) { | ||
| 1637 | xfs_dir_leaf_moveents(drop_leaf, 0, save_leaf, 0, | ||
| 1638 | be16_to_cpu(drop_hdr->count), mp); | ||
| 1639 | } else { | ||
| 1640 | xfs_dir_leaf_moveents(drop_leaf, 0, | ||
| 1641 | save_leaf, be16_to_cpu(save_hdr->count), | ||
| 1642 | be16_to_cpu(drop_hdr->count), mp); | ||
| 1643 | } | ||
| 1644 | } else { | ||
| 1645 | /* | ||
| 1646 | * Destination has holes, so we make a temporary copy | ||
| 1647 | * of the leaf and add them both to that. | ||
| 1648 | */ | ||
| 1649 | tmpbuffer = kmem_alloc(state->blocksize, KM_SLEEP); | ||
| 1650 | ASSERT(tmpbuffer != NULL); | ||
| 1651 | memset(tmpbuffer, 0, state->blocksize); | ||
| 1652 | tmp_leaf = (xfs_dir_leafblock_t *)tmpbuffer; | ||
| 1653 | tmp_hdr = &tmp_leaf->hdr; | ||
| 1654 | tmp_hdr->info = save_hdr->info; /* struct copy */ | ||
| 1655 | tmp_hdr->count = 0; | ||
| 1656 | tmp_hdr->firstused = cpu_to_be16(state->blocksize); | ||
| 1657 | if (!tmp_hdr->firstused) | ||
| 1658 | tmp_hdr->firstused = cpu_to_be16(state->blocksize - 1); | ||
| 1659 | tmp_hdr->namebytes = 0; | ||
| 1660 | if (xfs_dir_leaf_order(save_blk->bp, drop_blk->bp)) { | ||
| 1661 | xfs_dir_leaf_moveents(drop_leaf, 0, tmp_leaf, 0, | ||
| 1662 | be16_to_cpu(drop_hdr->count), mp); | ||
| 1663 | xfs_dir_leaf_moveents(save_leaf, 0, | ||
| 1664 | tmp_leaf, be16_to_cpu(tmp_leaf->hdr.count), | ||
| 1665 | be16_to_cpu(save_hdr->count), mp); | ||
| 1666 | } else { | ||
| 1667 | xfs_dir_leaf_moveents(save_leaf, 0, tmp_leaf, 0, | ||
| 1668 | be16_to_cpu(save_hdr->count), mp); | ||
| 1669 | xfs_dir_leaf_moveents(drop_leaf, 0, | ||
| 1670 | tmp_leaf, be16_to_cpu(tmp_leaf->hdr.count), | ||
| 1671 | be16_to_cpu(drop_hdr->count), mp); | ||
| 1672 | } | ||
| 1673 | memcpy(save_leaf, tmp_leaf, state->blocksize); | ||
| 1674 | kmem_free(tmpbuffer, state->blocksize); | ||
| 1675 | } | ||
| 1676 | |||
| 1677 | xfs_da_log_buf(state->args->trans, save_blk->bp, 0, | ||
| 1678 | state->blocksize - 1); | ||
| 1679 | |||
| 1680 | /* | ||
| 1681 | * Copy out last hashval in each block for B-tree code. | ||
| 1682 | */ | ||
| 1683 | save_blk->hashval = be32_to_cpu(save_leaf->entries[ | ||
| 1684 | be16_to_cpu(save_leaf->hdr.count)-1].hashval); | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | /*======================================================================== | ||
| 1688 | * Routines used for finding things in the Btree. | ||
| 1689 | *========================================================================*/ | ||
| 1690 | |||
| 1691 | /* | ||
| 1692 | * Look up a name in a leaf directory structure. | ||
| 1693 | * This is the internal routine, it uses the caller's buffer. | ||
| 1694 | * | ||
| 1695 | * Note that duplicate keys are allowed, but only check within the | ||
| 1696 | * current leaf node. The Btree code must check in adjacent leaf nodes. | ||
| 1697 | * | ||
| 1698 | * Return in *index the index into the entry[] array of either the found | ||
| 1699 | * entry, or where the entry should have been (insert before that entry). | ||
| 1700 | * | ||
| 1701 | * Don't change the args->inumber unless we find the filename. | ||
| 1702 | */ | ||
| 1703 | int | ||
| 1704 | xfs_dir_leaf_lookup_int(xfs_dabuf_t *bp, xfs_da_args_t *args, int *index) | ||
| 1705 | { | ||
| 1706 | xfs_dir_leafblock_t *leaf; | ||
| 1707 | xfs_dir_leaf_entry_t *entry; | ||
| 1708 | xfs_dir_leaf_name_t *namest; | ||
| 1709 | int probe, span; | ||
| 1710 | xfs_dahash_t hashval; | ||
| 1711 | |||
| 1712 | leaf = bp->data; | ||
| 1713 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1714 | ASSERT(be16_to_cpu(leaf->hdr.count) < (XFS_LBSIZE(args->dp->i_mount)/8)); | ||
| 1715 | |||
| 1716 | /* | ||
| 1717 | * Binary search. (note: small blocks will skip this loop) | ||
| 1718 | */ | ||
| 1719 | hashval = args->hashval; | ||
| 1720 | probe = span = be16_to_cpu(leaf->hdr.count) / 2; | ||
| 1721 | for (entry = &leaf->entries[probe]; span > 4; | ||
| 1722 | entry = &leaf->entries[probe]) { | ||
| 1723 | span /= 2; | ||
| 1724 | if (be32_to_cpu(entry->hashval) < hashval) | ||
| 1725 | probe += span; | ||
| 1726 | else if (be32_to_cpu(entry->hashval) > hashval) | ||
| 1727 | probe -= span; | ||
| 1728 | else | ||
| 1729 | break; | ||
| 1730 | } | ||
| 1731 | ASSERT((probe >= 0) && \ | ||
| 1732 | ((!leaf->hdr.count) || (probe < be16_to_cpu(leaf->hdr.count)))); | ||
| 1733 | ASSERT((span <= 4) || (be32_to_cpu(entry->hashval) == hashval)); | ||
| 1734 | |||
| 1735 | /* | ||
| 1736 | * Since we may have duplicate hashval's, find the first matching | ||
| 1737 | * hashval in the leaf. | ||
| 1738 | */ | ||
| 1739 | while ((probe > 0) && (be32_to_cpu(entry->hashval) >= hashval)) { | ||
| 1740 | entry--; | ||
| 1741 | probe--; | ||
| 1742 | } | ||
| 1743 | while ((probe < be16_to_cpu(leaf->hdr.count)) && | ||
| 1744 | (be32_to_cpu(entry->hashval) < hashval)) { | ||
| 1745 | entry++; | ||
| 1746 | probe++; | ||
| 1747 | } | ||
| 1748 | if ((probe == be16_to_cpu(leaf->hdr.count)) || | ||
| 1749 | (be32_to_cpu(entry->hashval) != hashval)) { | ||
| 1750 | *index = probe; | ||
| 1751 | ASSERT(args->oknoent); | ||
| 1752 | return XFS_ERROR(ENOENT); | ||
| 1753 | } | ||
| 1754 | |||
| 1755 | /* | ||
| 1756 | * Duplicate keys may be present, so search all of them for a match. | ||
| 1757 | */ | ||
| 1758 | while ((probe < be16_to_cpu(leaf->hdr.count)) && | ||
| 1759 | (be32_to_cpu(entry->hashval) == hashval)) { | ||
| 1760 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, be16_to_cpu(entry->nameidx)); | ||
| 1761 | if (entry->namelen == args->namelen && | ||
| 1762 | namest->name[0] == args->name[0] && | ||
| 1763 | memcmp(args->name, namest->name, args->namelen) == 0) { | ||
| 1764 | XFS_DIR_SF_GET_DIRINO(&namest->inumber, &args->inumber); | ||
| 1765 | *index = probe; | ||
| 1766 | return XFS_ERROR(EEXIST); | ||
| 1767 | } | ||
| 1768 | entry++; | ||
| 1769 | probe++; | ||
| 1770 | } | ||
| 1771 | *index = probe; | ||
| 1772 | ASSERT(probe == be16_to_cpu(leaf->hdr.count) || args->oknoent); | ||
| 1773 | return XFS_ERROR(ENOENT); | ||
| 1774 | } | ||
| 1775 | |||
| 1776 | /*======================================================================== | ||
| 1777 | * Utility routines. | ||
| 1778 | *========================================================================*/ | ||
| 1779 | |||
| 1780 | /* | ||
| 1781 | * Move the indicated entries from one leaf to another. | ||
| 1782 | * NOTE: this routine modifies both source and destination leaves. | ||
| 1783 | */ | ||
| 1784 | /* ARGSUSED */ | ||
| 1785 | STATIC void | ||
| 1786 | xfs_dir_leaf_moveents(xfs_dir_leafblock_t *leaf_s, int start_s, | ||
| 1787 | xfs_dir_leafblock_t *leaf_d, int start_d, | ||
| 1788 | int count, xfs_mount_t *mp) | ||
| 1789 | { | ||
| 1790 | xfs_dir_leaf_hdr_t *hdr_s, *hdr_d; | ||
| 1791 | xfs_dir_leaf_entry_t *entry_s, *entry_d; | ||
| 1792 | int tmp, i; | ||
| 1793 | |||
| 1794 | /* | ||
| 1795 | * Check for nothing to do. | ||
| 1796 | */ | ||
| 1797 | if (count == 0) | ||
| 1798 | return; | ||
| 1799 | |||
| 1800 | /* | ||
| 1801 | * Set up environment. | ||
| 1802 | */ | ||
| 1803 | ASSERT(be16_to_cpu(leaf_s->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1804 | ASSERT(be16_to_cpu(leaf_d->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1805 | hdr_s = &leaf_s->hdr; | ||
| 1806 | hdr_d = &leaf_d->hdr; | ||
| 1807 | ASSERT(hdr_s->count && (be16_to_cpu(hdr_s->count) < (XFS_LBSIZE(mp)/8))); | ||
| 1808 | ASSERT(be16_to_cpu(hdr_s->firstused) >= | ||
| 1809 | ((be16_to_cpu(hdr_s->count)*sizeof(*entry_s))+sizeof(*hdr_s))); | ||
| 1810 | ASSERT(be16_to_cpu(hdr_d->count) < (XFS_LBSIZE(mp)/8)); | ||
| 1811 | ASSERT(be16_to_cpu(hdr_d->firstused) >= | ||
| 1812 | ((be16_to_cpu(hdr_d->count)*sizeof(*entry_d))+sizeof(*hdr_d))); | ||
| 1813 | |||
| 1814 | ASSERT(start_s < be16_to_cpu(hdr_s->count)); | ||
| 1815 | ASSERT(start_d <= be16_to_cpu(hdr_d->count)); | ||
| 1816 | ASSERT(count <= be16_to_cpu(hdr_s->count)); | ||
| 1817 | |||
| 1818 | /* | ||
| 1819 | * Move the entries in the destination leaf up to make a hole? | ||
| 1820 | */ | ||
| 1821 | if (start_d < be16_to_cpu(hdr_d->count)) { | ||
| 1822 | tmp = be16_to_cpu(hdr_d->count) - start_d; | ||
| 1823 | tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1824 | entry_s = &leaf_d->entries[start_d]; | ||
| 1825 | entry_d = &leaf_d->entries[start_d + count]; | ||
| 1826 | memcpy(entry_d, entry_s, tmp); | ||
| 1827 | } | ||
| 1828 | |||
| 1829 | /* | ||
| 1830 | * Copy all entry's in the same (sorted) order, | ||
| 1831 | * but allocate filenames packed and in sequence. | ||
| 1832 | */ | ||
| 1833 | entry_s = &leaf_s->entries[start_s]; | ||
| 1834 | entry_d = &leaf_d->entries[start_d]; | ||
| 1835 | for (i = 0; i < count; entry_s++, entry_d++, i++) { | ||
| 1836 | ASSERT(be16_to_cpu(entry_s->nameidx) >= | ||
| 1837 | be16_to_cpu(hdr_s->firstused)); | ||
| 1838 | tmp = XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry_s); | ||
| 1839 | be16_add(&hdr_d->firstused, -(tmp)); | ||
| 1840 | entry_d->hashval = entry_s->hashval; | ||
| 1841 | entry_d->nameidx = hdr_d->firstused; | ||
| 1842 | entry_d->namelen = entry_s->namelen; | ||
| 1843 | ASSERT(be16_to_cpu(entry_d->nameidx) + tmp <= XFS_LBSIZE(mp)); | ||
| 1844 | memcpy(XFS_DIR_LEAF_NAMESTRUCT(leaf_d, be16_to_cpu(entry_d->nameidx)), | ||
| 1845 | XFS_DIR_LEAF_NAMESTRUCT(leaf_s, be16_to_cpu(entry_s->nameidx)), tmp); | ||
| 1846 | ASSERT(be16_to_cpu(entry_s->nameidx) + tmp <= XFS_LBSIZE(mp)); | ||
| 1847 | memset((char *)XFS_DIR_LEAF_NAMESTRUCT(leaf_s, | ||
| 1848 | be16_to_cpu(entry_s->nameidx)), 0, tmp); | ||
| 1849 | be16_add(&hdr_s->namebytes, -(entry_d->namelen)); | ||
| 1850 | be16_add(&hdr_d->namebytes, entry_d->namelen); | ||
| 1851 | be16_add(&hdr_s->count, -1); | ||
| 1852 | be16_add(&hdr_d->count, +1); | ||
| 1853 | tmp = be16_to_cpu(hdr_d->count) * (uint)sizeof(xfs_dir_leaf_entry_t) | ||
| 1854 | + (uint)sizeof(xfs_dir_leaf_hdr_t); | ||
| 1855 | ASSERT(be16_to_cpu(hdr_d->firstused) >= tmp); | ||
| 1856 | |||
| 1857 | } | ||
| 1858 | |||
| 1859 | /* | ||
| 1860 | * Zero out the entries we just copied. | ||
| 1861 | */ | ||
| 1862 | if (start_s == be16_to_cpu(hdr_s->count)) { | ||
| 1863 | tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1864 | entry_s = &leaf_s->entries[start_s]; | ||
| 1865 | ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp)); | ||
| 1866 | memset((char *)entry_s, 0, tmp); | ||
| 1867 | } else { | ||
| 1868 | /* | ||
| 1869 | * Move the remaining entries down to fill the hole, | ||
| 1870 | * then zero the entries at the top. | ||
| 1871 | */ | ||
| 1872 | tmp = be16_to_cpu(hdr_s->count) - count; | ||
| 1873 | tmp *= (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1874 | entry_s = &leaf_s->entries[start_s + count]; | ||
| 1875 | entry_d = &leaf_s->entries[start_s]; | ||
| 1876 | memcpy(entry_d, entry_s, tmp); | ||
| 1877 | |||
| 1878 | tmp = count * (uint)sizeof(xfs_dir_leaf_entry_t); | ||
| 1879 | entry_s = &leaf_s->entries[be16_to_cpu(hdr_s->count)]; | ||
| 1880 | ASSERT((char *)entry_s + tmp <= (char *)leaf_s + XFS_LBSIZE(mp)); | ||
| 1881 | memset((char *)entry_s, 0, tmp); | ||
| 1882 | } | ||
| 1883 | |||
| 1884 | /* | ||
| 1885 | * Fill in the freemap information | ||
| 1886 | */ | ||
| 1887 | hdr_d->freemap[0].base = cpu_to_be16(sizeof(xfs_dir_leaf_hdr_t) + | ||
| 1888 | be16_to_cpu(hdr_d->count) * sizeof(xfs_dir_leaf_entry_t)); | ||
| 1889 | hdr_d->freemap[0].size = cpu_to_be16(be16_to_cpu(hdr_d->firstused) - | ||
| 1890 | be16_to_cpu(hdr_d->freemap[0].base)); | ||
| 1891 | hdr_d->freemap[1].base = 0; | ||
| 1892 | hdr_d->freemap[1].size = 0; | ||
| 1893 | hdr_d->freemap[2].base = 0; | ||
| 1894 | hdr_d->freemap[2].size = 0; | ||
| 1895 | hdr_s->holes = 1; /* leaf may not be compact */ | ||
| 1896 | } | ||
| 1897 | |||
| 1898 | /* | ||
| 1899 | * Compare two leaf blocks "order". | ||
| 1900 | */ | ||
| 1901 | int | ||
| 1902 | xfs_dir_leaf_order(xfs_dabuf_t *leaf1_bp, xfs_dabuf_t *leaf2_bp) | ||
| 1903 | { | ||
| 1904 | xfs_dir_leafblock_t *leaf1, *leaf2; | ||
| 1905 | |||
| 1906 | leaf1 = leaf1_bp->data; | ||
| 1907 | leaf2 = leaf2_bp->data; | ||
| 1908 | ASSERT((be16_to_cpu(leaf1->hdr.info.magic) == XFS_DIR_LEAF_MAGIC) && | ||
| 1909 | (be16_to_cpu(leaf2->hdr.info.magic) == XFS_DIR_LEAF_MAGIC)); | ||
| 1910 | if (leaf1->hdr.count && leaf2->hdr.count && | ||
| 1911 | ((be32_to_cpu(leaf2->entries[0].hashval) < | ||
| 1912 | be32_to_cpu(leaf1->entries[0 ].hashval)) || | ||
| 1913 | (be32_to_cpu(leaf2->entries[ | ||
| 1914 | be16_to_cpu(leaf2->hdr.count)-1].hashval) < | ||
| 1915 | be32_to_cpu(leaf1->entries[ | ||
| 1916 | be16_to_cpu(leaf1->hdr.count)-1].hashval)))) { | ||
| 1917 | return 1; | ||
| 1918 | } | ||
| 1919 | return 0; | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | /* | ||
| 1923 | * Pick up the last hashvalue from a leaf block. | ||
| 1924 | */ | ||
| 1925 | xfs_dahash_t | ||
| 1926 | xfs_dir_leaf_lasthash(xfs_dabuf_t *bp, int *count) | ||
| 1927 | { | ||
| 1928 | xfs_dir_leafblock_t *leaf; | ||
| 1929 | |||
| 1930 | leaf = bp->data; | ||
| 1931 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR_LEAF_MAGIC); | ||
| 1932 | if (count) | ||
| 1933 | *count = be16_to_cpu(leaf->hdr.count); | ||
| 1934 | if (!leaf->hdr.count) | ||
| 1935 | return(0); | ||
| 1936 | return be32_to_cpu(leaf->entries[be16_to_cpu(leaf->hdr.count)-1].hashval); | ||
| 1937 | } | ||
| 1938 | |||
| 1939 | /* | ||
| 1940 | * Copy out directory entries for getdents(), for leaf directories. | ||
| 1941 | */ | ||
| 1942 | int | ||
| 1943 | xfs_dir_leaf_getdents_int( | ||
| 1944 | xfs_dabuf_t *bp, | ||
| 1945 | xfs_inode_t *dp, | ||
| 1946 | xfs_dablk_t bno, | ||
| 1947 | uio_t *uio, | ||
| 1948 | int *eobp, | ||
| 1949 | xfs_dirent_t *dbp, | ||
| 1950 | xfs_dir_put_t put, | ||
| 1951 | xfs_daddr_t nextda) | ||
| 1952 | { | ||
| 1953 | xfs_dir_leafblock_t *leaf; | ||
| 1954 | xfs_dir_leaf_entry_t *entry; | ||
| 1955 | xfs_dir_leaf_name_t *namest; | ||
| 1956 | int entno, want_entno, i, nextentno; | ||
| 1957 | xfs_mount_t *mp; | ||
| 1958 | xfs_dahash_t cookhash; | ||
| 1959 | xfs_dahash_t nexthash = 0; | ||
| 1960 | #if (BITS_PER_LONG == 32) | ||
| 1961 | xfs_dahash_t lasthash = XFS_DA_MAXHASH; | ||
| 1962 | #endif | ||
| 1963 | xfs_dir_put_args_t p; | ||
| 1964 | |||
| 1965 | mp = dp->i_mount; | ||
| 1966 | leaf = bp->data; | ||
| 1967 | if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR_LEAF_MAGIC) { | ||
| 1968 | *eobp = 1; | ||
| 1969 | return XFS_ERROR(ENOENT); /* XXX wrong code */ | ||
| 1970 | } | ||
| 1971 | |||
| 1972 | want_entno = XFS_DA_COOKIE_ENTRY(mp, uio->uio_offset); | ||
| 1973 | |||
| 1974 | cookhash = XFS_DA_COOKIE_HASH(mp, uio->uio_offset); | ||
| 1975 | |||
| 1976 | xfs_dir_trace_g_dul("leaf: start", dp, uio, leaf); | ||
| 1977 | |||
| 1978 | /* | ||
| 1979 | * Re-find our place. | ||
| 1980 | */ | ||
| 1981 | for (i = entno = 0, entry = &leaf->entries[0]; | ||
| 1982 | i < be16_to_cpu(leaf->hdr.count); entry++, i++) { | ||
| 1983 | |||
| 1984 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, | ||
| 1985 | be16_to_cpu(entry->nameidx)); | ||
| 1986 | |||
| 1987 | if (unlikely( | ||
| 1988 | ((char *)namest < (char *)leaf) || | ||
| 1989 | ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) { | ||
| 1990 | XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)", | ||
| 1991 | XFS_ERRLEVEL_LOW, mp, leaf); | ||
| 1992 | xfs_dir_trace_g_du("leaf: corrupted", dp, uio); | ||
| 1993 | return XFS_ERROR(EFSCORRUPTED); | ||
| 1994 | } | ||
| 1995 | if (be32_to_cpu(entry->hashval) >= cookhash) { | ||
| 1996 | if (entno < want_entno && | ||
| 1997 | be32_to_cpu(entry->hashval) == cookhash) { | ||
| 1998 | /* | ||
| 1999 | * Trying to get to a particular offset in a | ||
| 2000 | * run of equal-hashval entries. | ||
| 2001 | */ | ||
| 2002 | entno++; | ||
| 2003 | } else if (want_entno > 0 && entno == want_entno && | ||
| 2004 | be32_to_cpu(entry->hashval) == cookhash) { | ||
| 2005 | break; | ||
| 2006 | } else { | ||
| 2007 | entno = 0; | ||
| 2008 | break; | ||
| 2009 | } | ||
| 2010 | } | ||
| 2011 | } | ||
| 2012 | |||
| 2013 | if (i == be16_to_cpu(leaf->hdr.count)) { | ||
| 2014 | xfs_dir_trace_g_du("leaf: hash not found", dp, uio); | ||
| 2015 | if (!leaf->hdr.info.forw) | ||
| 2016 | uio->uio_offset = | ||
| 2017 | XFS_DA_MAKE_COOKIE(mp, 0, 0, XFS_DA_MAXHASH); | ||
| 2018 | /* | ||
| 2019 | * Don't set uio_offset if there's another block: | ||
| 2020 | * the node code will be setting uio_offset anyway. | ||
| 2021 | */ | ||
| 2022 | *eobp = 0; | ||
| 2023 | return 0; | ||
| 2024 | } | ||
| 2025 | xfs_dir_trace_g_due("leaf: hash found", dp, uio, entry); | ||
| 2026 | |||
| 2027 | p.dbp = dbp; | ||
| 2028 | p.put = put; | ||
| 2029 | p.uio = uio; | ||
| 2030 | |||
| 2031 | /* | ||
| 2032 | * We're synchronized, start copying entries out to the user. | ||
| 2033 | */ | ||
| 2034 | for (; entno >= 0 && i < be16_to_cpu(leaf->hdr.count); | ||
| 2035 | entry++, i++, (entno = nextentno)) { | ||
| 2036 | int lastresid=0, retval; | ||
| 2037 | xfs_dircook_t lastoffset; | ||
| 2038 | xfs_dahash_t thishash; | ||
| 2039 | |||
| 2040 | /* | ||
| 2041 | * Check for a damaged directory leaf block and pick up | ||
| 2042 | * the inode number from this entry. | ||
| 2043 | */ | ||
| 2044 | namest = XFS_DIR_LEAF_NAMESTRUCT(leaf, | ||
| 2045 | be16_to_cpu(entry->nameidx)); | ||
| 2046 | |||
| 2047 | if (unlikely( | ||
| 2048 | ((char *)namest < (char *)leaf) || | ||
| 2049 | ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) { | ||
| 2050 | XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)", | ||
| 2051 | XFS_ERRLEVEL_LOW, mp, leaf); | ||
| 2052 | xfs_dir_trace_g_du("leaf: corrupted", dp, uio); | ||
| 2053 | return XFS_ERROR(EFSCORRUPTED); | ||
| 2054 | } | ||
| 2055 | |||
| 2056 | xfs_dir_trace_g_duc("leaf: middle cookie ", | ||
| 2057 | dp, uio, p.cook.o); | ||
| 2058 | |||
| 2059 | if (i < (be16_to_cpu(leaf->hdr.count) - 1)) { | ||
| 2060 | nexthash = be32_to_cpu(entry[1].hashval); | ||
| 2061 | |||
| 2062 | if (nexthash == be32_to_cpu(entry->hashval)) | ||
| 2063 | nextentno = entno + 1; | ||
| 2064 | else | ||
| 2065 | nextentno = 0; | ||
| 2066 | XFS_PUT_COOKIE(p.cook, mp, bno, nextentno, nexthash); | ||
| 2067 | xfs_dir_trace_g_duc("leaf: middle cookie ", | ||
| 2068 | dp, uio, p.cook.o); | ||
| 2069 | |||
| 2070 | } else if ((thishash = be32_to_cpu(leaf->hdr.info.forw))) { | ||
| 2071 | xfs_dabuf_t *bp2; | ||
| 2072 | xfs_dir_leafblock_t *leaf2; | ||
| 2073 | |||
| 2074 | ASSERT(nextda != -1); | ||
| 2075 | |||
| 2076 | retval = xfs_da_read_buf(dp->i_transp, dp, thishash, | ||
| 2077 | nextda, &bp2, XFS_DATA_FORK); | ||
| 2078 | if (retval) | ||
| 2079 | return retval; | ||
| 2080 | |||
| 2081 | ASSERT(bp2 != NULL); | ||
| 2082 | |||
| 2083 | leaf2 = bp2->data; | ||
| 2084 | |||
| 2085 | if (unlikely( | ||
| 2086 | (be16_to_cpu(leaf2->hdr.info.magic) | ||
| 2087 | != XFS_DIR_LEAF_MAGIC) | ||
| 2088 | || (be32_to_cpu(leaf2->hdr.info.back) | ||
| 2089 | != bno))) { /* GROT */ | ||
| 2090 | XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(3)", | ||
| 2091 | XFS_ERRLEVEL_LOW, mp, | ||
| 2092 | leaf2); | ||
| 2093 | xfs_da_brelse(dp->i_transp, bp2); | ||
| 2094 | |||
| 2095 | return XFS_ERROR(EFSCORRUPTED); | ||
| 2096 | } | ||
| 2097 | |||
| 2098 | nexthash = be32_to_cpu(leaf2->entries[0].hashval); | ||
| 2099 | nextentno = -1; | ||
| 2100 | XFS_PUT_COOKIE(p.cook, mp, thishash, 0, nexthash); | ||
| 2101 | xfs_da_brelse(dp->i_transp, bp2); | ||
| 2102 | xfs_dir_trace_g_duc("leaf: next blk cookie", | ||
| 2103 | dp, uio, p.cook.o); | ||
| 2104 | } else { | ||
| 2105 | nextentno = -1; | ||
| 2106 | XFS_PUT_COOKIE(p.cook, mp, 0, 0, XFS_DA_MAXHASH); | ||
| 2107 | } | ||
| 2108 | |||
| 2109 | /* | ||
| 2110 | * Save off the cookie so we can fall back should the | ||
| 2111 | * 'put' into the outgoing buffer fails. To handle a run | ||
| 2112 | * of equal-hashvals, the off_t structure on 64bit | ||
| 2113 | * builds has entno built into the cookie to ID the | ||
| 2114 | * entry. On 32bit builds, we only have space for the | ||
| 2115 | * hashval so we can't ID specific entries within a group | ||
| 2116 | * of same hashval entries. For this, lastoffset is set | ||
| 2117 | * to the first in the run of equal hashvals so we don't | ||
| 2118 | * include any entries unless we can include all entries | ||
| 2119 | * that share the same hashval. Hopefully the buffer | ||
| 2120 | * provided is big enough to handle it (see pv763517). | ||
| 2121 | */ | ||
| 2122 | thishash = be32_to_cpu(entry->hashval); | ||
| 2123 | #if (BITS_PER_LONG == 32) | ||
| 2124 | if (thishash != lasthash) { | ||
| 2125 | XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash); | ||
| 2126 | lastresid = uio->uio_resid; | ||
| 2127 | lasthash = thishash; | ||
| 2128 | } else { | ||
| 2129 | xfs_dir_trace_g_duc("leaf: DUP COOKIES, skipped", | ||
| 2130 | dp, uio, p.cook.o); | ||
| 2131 | } | ||
| 2132 | #else | ||
| 2133 | XFS_PUT_COOKIE(lastoffset, mp, bno, entno, thishash); | ||
| 2134 | lastresid = uio->uio_resid; | ||
| 2135 | #endif /* BITS_PER_LONG == 32 */ | ||
| 2136 | |||
| 2137 | /* | ||
| 2138 | * Put the current entry into the outgoing buffer. If we fail | ||
| 2139 | * then restore the UIO to the first entry in the current | ||
| 2140 | * run of equal-hashval entries (probably one 1 entry long). | ||
| 2141 | */ | ||
| 2142 | p.ino = XFS_GET_DIR_INO8(namest->inumber); | ||
| 2143 | #if XFS_BIG_INUMS | ||
| 2144 | p.ino += mp->m_inoadd; | ||
| 2145 | #endif | ||
| 2146 | p.name = (char *)namest->name; | ||
| 2147 | p.namelen = entry->namelen; | ||
| 2148 | |||
| 2149 | retval = p.put(&p); | ||
| 2150 | |||
| 2151 | if (!p.done) { | ||
| 2152 | uio->uio_offset = lastoffset.o; | ||
| 2153 | uio->uio_resid = lastresid; | ||
| 2154 | |||
| 2155 | *eobp = 1; | ||
| 2156 | |||
| 2157 | xfs_dir_trace_g_du("leaf: E-O-B", dp, uio); | ||
| 2158 | |||
| 2159 | return retval; | ||
| 2160 | } | ||
| 2161 | } | ||
| 2162 | |||
| 2163 | uio->uio_offset = p.cook.o; | ||
| 2164 | |||
| 2165 | *eobp = 0; | ||
| 2166 | |||
| 2167 | xfs_dir_trace_g_du("leaf: E-O-F", dp, uio); | ||
| 2168 | |||
| 2169 | return 0; | ||
| 2170 | } | ||
| 2171 | |||
| 2172 | /* | ||
| 2173 | * Format a dirent64 structure and copy it out the the user's buffer. | ||
| 2174 | */ | ||
| 2175 | int | ||
| 2176 | xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa) | ||
| 2177 | { | ||
| 2178 | iovec_t *iovp; | ||
| 2179 | int reclen, namelen; | ||
| 2180 | xfs_dirent_t *idbp; | ||
| 2181 | uio_t *uio; | ||
| 2182 | |||
| 2183 | namelen = pa->namelen; | ||
| 2184 | reclen = DIRENTSIZE(namelen); | ||
| 2185 | uio = pa->uio; | ||
| 2186 | if (reclen > uio->uio_resid) { | ||
| 2187 | pa->done = 0; | ||
| 2188 | return 0; | ||
| 2189 | } | ||
| 2190 | iovp = uio->uio_iov; | ||
| 2191 | idbp = (xfs_dirent_t *)iovp->iov_base; | ||
| 2192 | iovp->iov_base = (char *)idbp + reclen; | ||
| 2193 | iovp->iov_len -= reclen; | ||
| 2194 | uio->uio_resid -= reclen; | ||
| 2195 | idbp->d_reclen = reclen; | ||
| 2196 | idbp->d_ino = pa->ino; | ||
| 2197 | idbp->d_off = pa->cook.o; | ||
| 2198 | idbp->d_name[namelen] = '\0'; | ||
| 2199 | pa->done = 1; | ||
| 2200 | memcpy(idbp->d_name, pa->name, namelen); | ||
| 2201 | return 0; | ||
| 2202 | } | ||
| 2203 | |||
| 2204 | /* | ||
| 2205 | * Format a dirent64 structure and copy it out the the user's buffer. | ||
| 2206 | */ | ||
| 2207 | int | ||
| 2208 | xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa) | ||
| 2209 | { | ||
| 2210 | int retval, reclen, namelen; | ||
| 2211 | xfs_dirent_t *idbp; | ||
| 2212 | uio_t *uio; | ||
| 2213 | |||
| 2214 | namelen = pa->namelen; | ||
| 2215 | reclen = DIRENTSIZE(namelen); | ||
| 2216 | uio = pa->uio; | ||
| 2217 | if (reclen > uio->uio_resid) { | ||
| 2218 | pa->done = 0; | ||
| 2219 | return 0; | ||
| 2220 | } | ||
| 2221 | idbp = pa->dbp; | ||
| 2222 | idbp->d_reclen = reclen; | ||
| 2223 | idbp->d_ino = pa->ino; | ||
| 2224 | idbp->d_off = pa->cook.o; | ||
| 2225 | idbp->d_name[namelen] = '\0'; | ||
| 2226 | memcpy(idbp->d_name, pa->name, namelen); | ||
| 2227 | retval = uio_read((caddr_t)idbp, reclen, uio); | ||
| 2228 | pa->done = (retval == 0); | ||
| 2229 | return retval; | ||
| 2230 | } | ||
diff --git a/fs/xfs/xfs_dir_leaf.h b/fs/xfs/xfs_dir_leaf.h index 7ca5845195d5..e69de29bb2d1 100644 --- a/fs/xfs/xfs_dir_leaf.h +++ b/fs/xfs/xfs_dir_leaf.h | |||
| @@ -1,231 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write the Free Software Foundation, | ||
| 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | #ifndef __XFS_DIR_LEAF_H__ | ||
| 19 | #define __XFS_DIR_LEAF_H__ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Directory layout, internal structure, access macros, etc. | ||
| 23 | * | ||
| 24 | * Large directories are structured around Btrees where all the data | ||
| 25 | * elements are in the leaf nodes. Filenames are hashed into an int, | ||
| 26 | * then that int is used as the index into the Btree. Since the hashval | ||
| 27 | * of a filename may not be unique, we may have duplicate keys. The | ||
| 28 | * internal links in the Btree are logical block offsets into the file. | ||
| 29 | */ | ||
| 30 | |||
| 31 | struct uio; | ||
| 32 | struct xfs_bmap_free; | ||
| 33 | struct xfs_dabuf; | ||
| 34 | struct xfs_da_args; | ||
| 35 | struct xfs_da_state; | ||
| 36 | struct xfs_da_state_blk; | ||
| 37 | struct xfs_dir_put_args; | ||
| 38 | struct xfs_inode; | ||
| 39 | struct xfs_mount; | ||
| 40 | struct xfs_trans; | ||
| 41 | |||
| 42 | /*======================================================================== | ||
| 43 | * Directory Structure when equal to XFS_LBSIZE(mp) bytes. | ||
| 44 | *========================================================================*/ | ||
| 45 | |||
| 46 | /* | ||
| 47 | * This is the structure of the leaf nodes in the Btree. | ||
| 48 | * | ||
| 49 | * Struct leaf_entry's are packed from the top. Names grow from the bottom | ||
| 50 | * but are not packed. The freemap contains run-length-encoded entries | ||
| 51 | * for the free bytes after the leaf_entry's, but only the N largest such, | ||
| 52 | * smaller runs are dropped. When the freemap doesn't show enough space | ||
| 53 | * for an allocation, we compact the namelist area and try again. If we | ||
| 54 | * still don't have enough space, then we have to split the block. | ||
| 55 | * | ||
| 56 | * Since we have duplicate hash keys, for each key that matches, compare | ||
| 57 | * the actual string. The root and intermediate node search always takes | ||
| 58 | * the first-in-the-block key match found, so we should only have to work | ||
| 59 | * "forw"ard. If none matches, continue with the "forw"ard leaf nodes | ||
| 60 | * until the hash key changes or the filename is found. | ||
| 61 | * | ||
| 62 | * The parent directory and the self-pointer are explicitly represented | ||
| 63 | * (ie: there are entries for "." and ".."). | ||
| 64 | * | ||
| 65 | * Note that the count being a __uint16_t limits us to something like a | ||
| 66 | * blocksize of 1.3MB in the face of worst case (short) filenames. | ||
| 67 | */ | ||
| 68 | #define XFS_DIR_LEAF_MAPSIZE 3 /* how many freespace slots */ | ||
| 69 | |||
| 70 | typedef struct xfs_dir_leaf_map { /* RLE map of free bytes */ | ||
| 71 | __be16 base; /* base of free region */ | ||
| 72 | __be16 size; /* run length of free region */ | ||
| 73 | } xfs_dir_leaf_map_t; | ||
| 74 | |||
| 75 | typedef struct xfs_dir_leaf_hdr { /* constant-structure header block */ | ||
| 76 | xfs_da_blkinfo_t info; /* block type, links, etc. */ | ||
| 77 | __be16 count; /* count of active leaf_entry's */ | ||
| 78 | __be16 namebytes; /* num bytes of name strings stored */ | ||
| 79 | __be16 firstused; /* first used byte in name area */ | ||
| 80 | __u8 holes; /* != 0 if blk needs compaction */ | ||
| 81 | __u8 pad1; | ||
| 82 | xfs_dir_leaf_map_t freemap[XFS_DIR_LEAF_MAPSIZE]; | ||
| 83 | } xfs_dir_leaf_hdr_t; | ||
| 84 | |||
| 85 | typedef struct xfs_dir_leaf_entry { /* sorted on key, not name */ | ||
| 86 | __be32 hashval; /* hash value of name */ | ||
| 87 | __be16 nameidx; /* index into buffer of name */ | ||
| 88 | __u8 namelen; /* length of name string */ | ||
| 89 | __u8 pad2; | ||
| 90 | } xfs_dir_leaf_entry_t; | ||
| 91 | |||
| 92 | typedef struct xfs_dir_leaf_name { | ||
| 93 | xfs_dir_ino_t inumber; /* inode number for this key */ | ||
| 94 | __uint8_t name[1]; /* name string itself */ | ||
| 95 | } xfs_dir_leaf_name_t; | ||
| 96 | |||
| 97 | typedef struct xfs_dir_leafblock { | ||
| 98 | xfs_dir_leaf_hdr_t hdr; /* constant-structure header block */ | ||
| 99 | xfs_dir_leaf_entry_t entries[1]; /* var sized array */ | ||
| 100 | xfs_dir_leaf_name_t namelist[1]; /* grows from bottom of buf */ | ||
| 101 | } xfs_dir_leafblock_t; | ||
| 102 | |||
| 103 | /* | ||
| 104 | * Length of name for which a 512-byte block filesystem | ||
| 105 | * can get a double split. | ||
| 106 | */ | ||
| 107 | #define XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN \ | ||
| 108 | (512 - (uint)sizeof(xfs_dir_leaf_hdr_t) - \ | ||
| 109 | (uint)sizeof(xfs_dir_leaf_entry_t) * 2 - \ | ||
| 110 | (uint)sizeof(xfs_dir_leaf_name_t) * 2 - (MAXNAMELEN - 2) + 1 + 1) | ||
| 111 | |||
| 112 | typedef int (*xfs_dir_put_t)(struct xfs_dir_put_args *pa); | ||
| 113 | |||
| 114 | typedef union { | ||
| 115 | xfs_off_t o; /* offset (cookie) */ | ||
| 116 | /* | ||
| 117 | * Watch the order here (endian-ness dependent). | ||
| 118 | */ | ||
| 119 | struct { | ||
| 120 | #ifndef XFS_NATIVE_HOST | ||
| 121 | xfs_dahash_t h; /* hash value */ | ||
| 122 | __uint32_t be; /* block and entry */ | ||
| 123 | #else | ||
| 124 | __uint32_t be; /* block and entry */ | ||
| 125 | xfs_dahash_t h; /* hash value */ | ||
| 126 | #endif /* XFS_NATIVE_HOST */ | ||
| 127 | } s; | ||
| 128 | } xfs_dircook_t; | ||
| 129 | |||
| 130 | #define XFS_PUT_COOKIE(c,mp,bno,entry,hash) \ | ||
| 131 | ((c).s.be = XFS_DA_MAKE_BNOENTRY(mp, bno, entry), (c).s.h = (hash)) | ||
| 132 | |||
| 133 | typedef struct xfs_dir_put_args { | ||
| 134 | xfs_dircook_t cook; /* cookie of (next) entry */ | ||
| 135 | xfs_intino_t ino; /* inode number */ | ||
| 136 | struct xfs_dirent *dbp; /* buffer pointer */ | ||
| 137 | char *name; /* directory entry name */ | ||
| 138 | int namelen; /* length of name */ | ||
| 139 | int done; /* output: set if value was stored */ | ||
| 140 | xfs_dir_put_t put; /* put function ptr (i/o) */ | ||
| 141 | struct uio *uio; /* uio control structure */ | ||
| 142 | } xfs_dir_put_args_t; | ||
| 143 | |||
| 144 | #define XFS_DIR_LEAF_ENTSIZE_BYNAME(len) \ | ||
| 145 | xfs_dir_leaf_entsize_byname(len) | ||
| 146 | static inline int xfs_dir_leaf_entsize_byname(int len) | ||
| 147 | { | ||
| 148 | return (uint)sizeof(xfs_dir_leaf_name_t)-1 + len; | ||
| 149 | } | ||
| 150 | |||
| 151 | #define XFS_DIR_LEAF_ENTSIZE_BYENTRY(entry) \ | ||
| 152 | xfs_dir_leaf_entsize_byentry(entry) | ||
| 153 | static inline int xfs_dir_leaf_entsize_byentry(xfs_dir_leaf_entry_t *entry) | ||
| 154 | { | ||
| 155 | return (uint)sizeof(xfs_dir_leaf_name_t)-1 + (entry)->namelen; | ||
| 156 | } | ||
| 157 | |||
| 158 | #define XFS_DIR_LEAF_NAMESTRUCT(leafp,offset) \ | ||
| 159 | xfs_dir_leaf_namestruct(leafp,offset) | ||
| 160 | static inline xfs_dir_leaf_name_t * | ||
| 161 | xfs_dir_leaf_namestruct(xfs_dir_leafblock_t *leafp, int offset) | ||
| 162 | { | ||
| 163 | return (xfs_dir_leaf_name_t *)&((char *)(leafp))[offset]; | ||
| 164 | } | ||
| 165 | |||
| 166 | /*======================================================================== | ||
| 167 | * Function prototypes for the kernel. | ||
| 168 | *========================================================================*/ | ||
| 169 | |||
| 170 | /* | ||
| 171 | * Internal routines when dirsize < XFS_LITINO(mp). | ||
| 172 | */ | ||
| 173 | int xfs_dir_shortform_create(struct xfs_da_args *args, xfs_ino_t parent); | ||
| 174 | int xfs_dir_shortform_addname(struct xfs_da_args *args); | ||
| 175 | int xfs_dir_shortform_lookup(struct xfs_da_args *args); | ||
| 176 | int xfs_dir_shortform_to_leaf(struct xfs_da_args *args); | ||
| 177 | int xfs_dir_shortform_removename(struct xfs_da_args *args); | ||
| 178 | int xfs_dir_shortform_getdents(struct xfs_inode *dp, struct uio *uio, int *eofp, | ||
| 179 | struct xfs_dirent *dbp, xfs_dir_put_t put); | ||
| 180 | int xfs_dir_shortform_replace(struct xfs_da_args *args); | ||
| 181 | |||
| 182 | /* | ||
| 183 | * Internal routines when dirsize == XFS_LBSIZE(mp). | ||
| 184 | */ | ||
| 185 | int xfs_dir_leaf_to_node(struct xfs_da_args *args); | ||
| 186 | int xfs_dir_leaf_to_shortform(struct xfs_da_args *args); | ||
| 187 | |||
| 188 | /* | ||
| 189 | * Routines used for growing the Btree. | ||
| 190 | */ | ||
| 191 | int xfs_dir_leaf_split(struct xfs_da_state *state, | ||
| 192 | struct xfs_da_state_blk *oldblk, | ||
| 193 | struct xfs_da_state_blk *newblk); | ||
| 194 | int xfs_dir_leaf_add(struct xfs_dabuf *leaf_buffer, | ||
| 195 | struct xfs_da_args *args, int insertion_index); | ||
| 196 | int xfs_dir_leaf_addname(struct xfs_da_args *args); | ||
| 197 | int xfs_dir_leaf_lookup_int(struct xfs_dabuf *leaf_buffer, | ||
| 198 | struct xfs_da_args *args, | ||
| 199 | int *index_found_at); | ||
| 200 | int xfs_dir_leaf_remove(struct xfs_trans *trans, | ||
| 201 | struct xfs_dabuf *leaf_buffer, | ||
| 202 | int index_to_remove); | ||
| 203 | int xfs_dir_leaf_getdents_int(struct xfs_dabuf *bp, struct xfs_inode *dp, | ||
| 204 | xfs_dablk_t bno, struct uio *uio, | ||
| 205 | int *eobp, struct xfs_dirent *dbp, | ||
| 206 | xfs_dir_put_t put, xfs_daddr_t nextda); | ||
| 207 | |||
| 208 | /* | ||
| 209 | * Routines used for shrinking the Btree. | ||
| 210 | */ | ||
| 211 | int xfs_dir_leaf_toosmall(struct xfs_da_state *state, int *retval); | ||
| 212 | void xfs_dir_leaf_unbalance(struct xfs_da_state *state, | ||
| 213 | struct xfs_da_state_blk *drop_blk, | ||
| 214 | struct xfs_da_state_blk *save_blk); | ||
| 215 | |||
| 216 | /* | ||
| 217 | * Utility routines. | ||
| 218 | */ | ||
| 219 | uint xfs_dir_leaf_lasthash(struct xfs_dabuf *bp, int *count); | ||
| 220 | int xfs_dir_leaf_order(struct xfs_dabuf *leaf1_bp, | ||
| 221 | struct xfs_dabuf *leaf2_bp); | ||
| 222 | int xfs_dir_put_dirent64_direct(xfs_dir_put_args_t *pa); | ||
| 223 | int xfs_dir_put_dirent64_uio(xfs_dir_put_args_t *pa); | ||
| 224 | int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); | ||
| 225 | |||
| 226 | /* | ||
| 227 | * Global data. | ||
| 228 | */ | ||
| 229 | extern xfs_dahash_t xfs_dir_hash_dot, xfs_dir_hash_dotdot; | ||
| 230 | |||
| 231 | #endif /* __XFS_DIR_LEAF_H__ */ | ||
diff --git a/fs/xfs/xfs_dir_sf.h b/fs/xfs/xfs_dir_sf.h index 5b20b4d3f57d..e69de29bb2d1 100644 --- a/fs/xfs/xfs_dir_sf.h +++ b/fs/xfs/xfs_dir_sf.h | |||
| @@ -1,155 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000,2005 Silicon Graphics, Inc. | ||
| 3 | * All Rights Reserved. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or | ||
| 6 | * modify it under the terms of the GNU General Public License as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it would be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License | ||
| 15 | * along with this program; if not, write the Free Software Foundation, | ||
| 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 17 | */ | ||
| 18 | #ifndef __XFS_DIR_SF_H__ | ||
| 19 | #define __XFS_DIR_SF_H__ | ||
| 20 | |||
| 21 | /* | ||
| 22 | * Directory layout when stored internal to an inode. | ||
| 23 | * | ||
| 24 | * Small directories are packed as tightly as possible so as to | ||
| 25 | * fit into the literal area of the inode. | ||
| 26 | */ | ||
| 27 | |||
| 28 | typedef struct { __uint8_t i[sizeof(xfs_ino_t)]; } xfs_dir_ino_t; | ||
| 29 | |||
| 30 | /* | ||
| 31 | * The parent directory has a dedicated field, and the self-pointer must | ||
| 32 | * be calculated on the fly. | ||
| 33 | * | ||
| 34 | * Entries are packed toward the top as tight as possible. The header | ||
| 35 | * and the elements much be memcpy'd out into a work area to get correct | ||
| 36 | * alignment for the inode number fields. | ||
| 37 | */ | ||
| 38 | typedef struct xfs_dir_sf_hdr { /* constant-structure header block */ | ||
| 39 | xfs_dir_ino_t parent; /* parent dir inode number */ | ||
| 40 | __uint8_t count; /* count of active entries */ | ||
| 41 | } xfs_dir_sf_hdr_t; | ||
| 42 | |||
| 43 | typedef struct xfs_dir_sf_entry { | ||
| 44 | xfs_dir_ino_t inumber; /* referenced inode number */ | ||
| 45 | __uint8_t namelen; /* actual length of name (no NULL) */ | ||
| 46 | __uint8_t name[1]; /* name */ | ||
| 47 | } xfs_dir_sf_entry_t; | ||
| 48 | |||
| 49 | typedef struct xfs_dir_shortform { | ||
| 50 | xfs_dir_sf_hdr_t hdr; | ||
| 51 | xfs_dir_sf_entry_t list[1]; /* variable sized array */ | ||
| 52 | } xfs_dir_shortform_t; | ||
| 53 | |||
| 54 | /* | ||
| 55 | * We generate this then sort it, so that readdirs are returned in | ||
| 56 | * hash-order. Else seekdir won't work. | ||
| 57 | */ | ||
| 58 | typedef struct xfs_dir_sf_sort { | ||
| 59 | __uint8_t entno; /* .=0, ..=1, else entry# + 2 */ | ||
| 60 | __uint8_t seqno; /* sequence # with same hash value */ | ||
| 61 | __uint8_t namelen; /* length of name value (no null) */ | ||
| 62 | xfs_dahash_t hash; /* this entry's hash value */ | ||
| 63 | xfs_intino_t ino; /* this entry's inode number */ | ||
| 64 | char *name; /* name value, pointer into buffer */ | ||
| 65 | } xfs_dir_sf_sort_t; | ||
| 66 | |||
| 67 | #define XFS_DIR_SF_GET_DIRINO(from,to) xfs_dir_sf_get_dirino(from, to) | ||
| 68 | static inline void xfs_dir_sf_get_dirino(xfs_dir_ino_t *from, xfs_ino_t *to) | ||
| 69 | { | ||
| 70 | *(to) = XFS_GET_DIR_INO8(*from); | ||
| 71 | } | ||
| 72 | |||
| 73 | #define XFS_DIR_SF_PUT_DIRINO(from,to) xfs_dir_sf_put_dirino(from, to) | ||
| 74 | static inline void xfs_dir_sf_put_dirino(xfs_ino_t *from, xfs_dir_ino_t *to) | ||
| 75 | { | ||
| 76 | XFS_PUT_DIR_INO8(*(from), *(to)); | ||
| 77 | } | ||
| 78 | |||
| 79 | #define XFS_DIR_SF_ENTSIZE_BYNAME(len) xfs_dir_sf_entsize_byname(len) | ||
| 80 | static inline int xfs_dir_sf_entsize_byname(int len) | ||
| 81 | { | ||
| 82 | return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (len); | ||
| 83 | } | ||
| 84 | |||
| 85 | #define XFS_DIR_SF_ENTSIZE_BYENTRY(sfep) xfs_dir_sf_entsize_byentry(sfep) | ||
| 86 | static inline int xfs_dir_sf_entsize_byentry(xfs_dir_sf_entry_t *sfep) | ||
| 87 | { | ||
| 88 | return (uint)sizeof(xfs_dir_sf_entry_t)-1 + (sfep)->namelen; | ||
| 89 | } | ||
| 90 | |||
| 91 | #define XFS_DIR_SF_NEXTENTRY(sfep) xfs_dir_sf_nextentry(sfep) | ||
| 92 | static inline xfs_dir_sf_entry_t *xfs_dir_sf_nextentry(xfs_dir_sf_entry_t *sfep) | ||
| 93 | { | ||
| 94 | return (xfs_dir_sf_entry_t *) \ | ||
| 95 | ((char *)(sfep) + XFS_DIR_SF_ENTSIZE_BYENTRY(sfep)); | ||
| 96 | } | ||
| 97 | |||
| 98 | #define XFS_DIR_SF_ALLFIT(count,totallen) \ | ||
| 99 | xfs_dir_sf_allfit(count,totallen) | ||
| 100 | static inline int xfs_dir_sf_allfit(int count, int totallen) | ||
| 101 | { | ||
| 102 | return ((uint)sizeof(xfs_dir_sf_hdr_t) + \ | ||
| 103 | ((uint)sizeof(xfs_dir_sf_entry_t)-1)*(count) + (totallen)); | ||
| 104 | } | ||
| 105 | |||
| 106 | #if defined(XFS_DIR_TRACE) | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Kernel tracing support for directories. | ||
| 110 | */ | ||
| 111 | struct uio; | ||
| 112 | struct xfs_inode; | ||
| 113 | struct xfs_da_intnode; | ||
| 114 | struct xfs_dinode; | ||
| 115 | struct xfs_dir_leafblock; | ||
| 116 | struct xfs_dir_leaf_entry; | ||
| 117 | |||
| 118 | #define XFS_DIR_TRACE_SIZE 4096 /* size of global trace buffer */ | ||
| 119 | extern ktrace_t *xfs_dir_trace_buf; | ||
| 120 | |||
| 121 | /* | ||
| 122 | * Trace record types. | ||
| 123 | */ | ||
| 124 | #define XFS_DIR_KTRACE_G_DU 1 /* dp, uio */ | ||
| 125 | #define XFS_DIR_KTRACE_G_DUB 2 /* dp, uio, bno */ | ||
| 126 | #define XFS_DIR_KTRACE_G_DUN 3 /* dp, uio, node */ | ||
| 127 | #define XFS_DIR_KTRACE_G_DUL 4 /* dp, uio, leaf */ | ||
| 128 | #define XFS_DIR_KTRACE_G_DUE 5 /* dp, uio, leaf entry */ | ||
| 129 | #define XFS_DIR_KTRACE_G_DUC 6 /* dp, uio, cookie */ | ||
| 130 | |||
| 131 | void xfs_dir_trace_g_du(char *where, struct xfs_inode *dp, struct uio *uio); | ||
| 132 | void xfs_dir_trace_g_dub(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 133 | xfs_dablk_t bno); | ||
| 134 | void xfs_dir_trace_g_dun(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 135 | struct xfs_da_intnode *node); | ||
| 136 | void xfs_dir_trace_g_dul(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 137 | struct xfs_dir_leafblock *leaf); | ||
| 138 | void xfs_dir_trace_g_due(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 139 | struct xfs_dir_leaf_entry *entry); | ||
| 140 | void xfs_dir_trace_g_duc(char *where, struct xfs_inode *dp, struct uio *uio, | ||
| 141 | xfs_off_t cookie); | ||
| 142 | void xfs_dir_trace_enter(int type, char *where, | ||
| 143 | void *a0, void *a1, void *a2, void *a3, | ||
| 144 | void *a4, void *a5, void *a6, void *a7, | ||
| 145 | void *a8, void *a9, void *a10, void *a11); | ||
| 146 | #else | ||
| 147 | #define xfs_dir_trace_g_du(w,d,u) | ||
| 148 | #define xfs_dir_trace_g_dub(w,d,u,b) | ||
| 149 | #define xfs_dir_trace_g_dun(w,d,u,n) | ||
| 150 | #define xfs_dir_trace_g_dul(w,d,u,l) | ||
| 151 | #define xfs_dir_trace_g_due(w,d,u,e) | ||
| 152 | #define xfs_dir_trace_g_duc(w,d,u,c) | ||
| 153 | #endif /* DEBUG */ | ||
| 154 | |||
| 155 | #endif /* __XFS_DIR_SF_H__ */ | ||
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c index 629795b3b3d5..1e4a35ddf7f9 100644 --- a/fs/xfs/xfs_dmops.c +++ b/fs/xfs/xfs_dmops.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
| 29 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 2a21c5024017..b95681b03d81 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c | |||
| @@ -22,12 +22,10 @@ | |||
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| 28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 29 | #include "xfs_bmap_btree.h" | 28 | #include "xfs_bmap_btree.h" |
| 30 | #include "xfs_dir_sf.h" | ||
| 31 | #include "xfs_dir2_sf.h" | 29 | #include "xfs_dir2_sf.h" |
| 32 | #include "xfs_attr_sf.h" | 30 | #include "xfs_attr_sf.h" |
| 33 | #include "xfs_dinode.h" | 31 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 8b028f128547..6cf6d8769b97 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_buf_item.h" | 24 | #include "xfs_buf_item.h" |
| 25 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| 28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 29 | #include "xfs_trans_priv.h" | 28 | #include "xfs_trans_priv.h" |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 650d35f537b7..077629bab532 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.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" |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index 7e5ccfec92be..33164a85aa9d 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.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" |
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index 60c65683462d..616eeeb6953e 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.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" |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 7894b72a7177..0724df7fabb7 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.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" |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index e799f0d00873..5fa0adb7e173 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
| @@ -26,14 +26,12 @@ | |||
| 26 | #include "xfs_trans_priv.h" | 26 | #include "xfs_trans_priv.h" |
| 27 | #include "xfs_sb.h" | 27 | #include "xfs_sb.h" |
| 28 | #include "xfs_ag.h" | 28 | #include "xfs_ag.h" |
| 29 | #include "xfs_dir.h" | ||
| 30 | #include "xfs_dir2.h" | 29 | #include "xfs_dir2.h" |
| 31 | #include "xfs_dmapi.h" | 30 | #include "xfs_dmapi.h" |
| 32 | #include "xfs_mount.h" | 31 | #include "xfs_mount.h" |
| 33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
| 34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
| 35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
| 36 | #include "xfs_dir_sf.h" | ||
| 37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
| 38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
| 39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
| @@ -2925,13 +2923,6 @@ xfs_iflush_fork( | |||
| 2925 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); | 2923 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); |
| 2926 | memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); | 2924 | memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes); |
| 2927 | } | 2925 | } |
| 2928 | if (whichfork == XFS_DATA_FORK) { | ||
| 2929 | if (unlikely(XFS_DIR_SHORTFORM_VALIDATE_ONDISK(mp, dip))) { | ||
| 2930 | XFS_ERROR_REPORT("xfs_iflush_fork", | ||
| 2931 | XFS_ERRLEVEL_LOW, mp); | ||
| 2932 | return XFS_ERROR(EFSCORRUPTED); | ||
| 2933 | } | ||
| 2934 | } | ||
| 2935 | break; | 2926 | break; |
| 2936 | 2927 | ||
| 2937 | case XFS_DINODE_FMT_EXTENTS: | 2928 | case XFS_DINODE_FMT_EXTENTS: |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 2caa91b89714..f8e80d8e7237 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | #include "xfs_buf_item.h" | 25 | #include "xfs_buf_item.h" |
| 26 | #include "xfs_sb.h" | 26 | #include "xfs_sb.h" |
| 27 | #include "xfs_ag.h" | 27 | #include "xfs_ag.h" |
| 28 | #include "xfs_dir.h" | ||
| 29 | #include "xfs_dir2.h" | 28 | #include "xfs_dir2.h" |
| 30 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
| 31 | #include "xfs_mount.h" | 30 | #include "xfs_mount.h" |
| @@ -33,7 +32,6 @@ | |||
| 33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
| 34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
| 35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
| 36 | #include "xfs_dir_sf.h" | ||
| 37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
| 38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
| 39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c index 89441e69cdde..06d710c9ce4b 100644 --- a/fs/xfs/xfs_iocore.c +++ b/fs/xfs/xfs_iocore.c | |||
| @@ -24,7 +24,6 @@ | |||
| 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_dfrag.h" | 28 | #include "xfs_dfrag.h" |
| 30 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index d79055207fbf..f1949c16df15 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_alloc.h" | 27 | #include "xfs_alloc.h" |
| 29 | #include "xfs_dmapi.h" | 28 | #include "xfs_dmapi.h" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index a0182ced29c4..46249e4d1fea 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.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" |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 95d679cd4e75..d8f5d4cbe8b7 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
| @@ -24,7 +24,6 @@ | |||
| 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" |
| @@ -36,7 +35,6 @@ | |||
| 36 | #include "xfs_ialloc_btree.h" | 35 | #include "xfs_ialloc_btree.h" |
| 37 | #include "xfs_log_recover.h" | 36 | #include "xfs_log_recover.h" |
| 38 | #include "xfs_trans_priv.h" | 37 | #include "xfs_trans_priv.h" |
| 39 | #include "xfs_dir_sf.h" | ||
| 40 | #include "xfs_dir2_sf.h" | 38 | #include "xfs_dir2_sf.h" |
| 41 | #include "xfs_attr_sf.h" | 39 | #include "xfs_attr_sf.h" |
| 42 | #include "xfs_dinode.h" | 40 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index f952f9dbf74a..55b4237c2153 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
| @@ -24,7 +24,6 @@ | |||
| 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" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
| 34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 5ce6416fbd33..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" |
| @@ -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. |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 761f42f989cd..b2bd4be4200a 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
| @@ -403,8 +403,6 @@ typedef struct xfs_mount { | |||
| 403 | __uint8_t m_inode_quiesce;/* call quiesce on new inodes. | 403 | __uint8_t m_inode_quiesce;/* call quiesce on new inodes. |
| 404 | field governed by m_ilock */ | 404 | field governed by m_ilock */ |
| 405 | __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ | 405 | __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ |
| 406 | __uint8_t m_dirversion; /* 1 or 2 */ | ||
| 407 | xfs_dirops_t m_dirops; /* table of dir funcs */ | ||
| 408 | int m_dirblksize; /* directory block sz--bytes */ | 406 | int m_dirblksize; /* directory block sz--bytes */ |
| 409 | int m_dirblkfsbs; /* directory block sz--fsbs */ | 407 | int m_dirblkfsbs; /* directory block sz--fsbs */ |
| 410 | xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ | 408 | xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ |
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c index 1408a32eef88..320d63ff9ca2 100644 --- a/fs/xfs/xfs_qmops.c +++ b/fs/xfs/xfs_qmops.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_ag.h" | 25 | #include "xfs_ag.h" |
| 26 | #include "xfs_dir.h" | ||
| 27 | #include "xfs_dir2.h" | 26 | #include "xfs_dir2.h" |
| 28 | #include "xfs_dmapi.h" | 27 | #include "xfs_dmapi.h" |
| 29 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 7d5f9b6ffdb8..d98171deaa1c 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
| @@ -22,13 +22,11 @@ | |||
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dir2.h" | 25 | #include "xfs_dir2.h" |
| 27 | #include "xfs_dmapi.h" | 26 | #include "xfs_dmapi.h" |
| 28 | #include "xfs_mount.h" | 27 | #include "xfs_mount.h" |
| 29 | #include "xfs_da_btree.h" | 28 | #include "xfs_da_btree.h" |
| 30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
| 31 | #include "xfs_dir_sf.h" | ||
| 32 | #include "xfs_dir2_sf.h" | 30 | #include "xfs_dir2_sf.h" |
| 33 | #include "xfs_attr_sf.h" | 31 | #include "xfs_attr_sf.h" |
| 34 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
| @@ -40,7 +38,6 @@ | |||
| 40 | #include "xfs_refcache.h" | 38 | #include "xfs_refcache.h" |
| 41 | #include "xfs_utils.h" | 39 | #include "xfs_utils.h" |
| 42 | #include "xfs_trans_space.h" | 40 | #include "xfs_trans_space.h" |
| 43 | #include "xfs_dir_leaf.h" | ||
| 44 | 41 | ||
| 45 | 42 | ||
| 46 | /* | 43 | /* |
| @@ -398,34 +395,29 @@ xfs_rename( | |||
| 398 | * fit before actually inserting it. | 395 | * fit before actually inserting it. |
| 399 | */ | 396 | */ |
| 400 | if (spaceres == 0 && | 397 | if (spaceres == 0 && |
| 401 | (error = XFS_DIR_CANENTER(mp, tp, target_dp, target_name, | 398 | (error = xfs_dir_canenter(tp, target_dp, target_name, |
| 402 | target_namelen))) { | 399 | target_namelen))) |
| 403 | goto error_return; | 400 | goto error_return; |
| 404 | } | ||
| 405 | /* | 401 | /* |
| 406 | * If target does not exist and the rename crosses | 402 | * If target does not exist and the rename crosses |
| 407 | * directories, adjust the target directory link count | 403 | * directories, adjust the target directory link count |
| 408 | * to account for the ".." reference from the new entry. | 404 | * to account for the ".." reference from the new entry. |
| 409 | */ | 405 | */ |
| 410 | error = XFS_DIR_CREATENAME(mp, tp, target_dp, target_name, | 406 | error = xfs_dir_createname(tp, target_dp, target_name, |
| 411 | target_namelen, src_ip->i_ino, | 407 | target_namelen, src_ip->i_ino, |
| 412 | &first_block, &free_list, spaceres); | 408 | &first_block, &free_list, spaceres); |
| 413 | if (error == ENOSPC) { | 409 | if (error == ENOSPC) |
| 414 | goto error_return; | 410 | goto error_return; |
| 415 | } | 411 | if (error) |
| 416 | if (error) { | ||
| 417 | goto abort_return; | 412 | goto abort_return; |
| 418 | } | ||
| 419 | xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 413 | xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
| 420 | 414 | ||
| 421 | if (new_parent && src_is_directory) { | 415 | if (new_parent && src_is_directory) { |
| 422 | error = xfs_bumplink(tp, target_dp); | 416 | error = xfs_bumplink(tp, target_dp); |
| 423 | if (error) { | 417 | if (error) |
| 424 | goto abort_return; | 418 | goto abort_return; |
| 425 | } | ||
| 426 | } | 419 | } |
| 427 | } else { /* target_ip != NULL */ | 420 | } else { /* target_ip != NULL */ |
| 428 | |||
| 429 | /* | 421 | /* |
| 430 | * If target exists and it's a directory, check that both | 422 | * If target exists and it's a directory, check that both |
| 431 | * target and source are directories and that target can be | 423 | * target and source are directories and that target can be |
| @@ -435,7 +427,7 @@ xfs_rename( | |||
| 435 | /* | 427 | /* |
| 436 | * Make sure target dir is empty. | 428 | * Make sure target dir is empty. |
| 437 | */ | 429 | */ |
| 438 | if (!(XFS_DIR_ISEMPTY(target_ip->i_mount, target_ip)) || | 430 | if (!(xfs_dir_isempty(target_ip)) || |
| 439 | (target_ip->i_d.di_nlink > 2)) { | 431 | (target_ip->i_d.di_nlink > 2)) { |
| 440 | error = XFS_ERROR(EEXIST); | 432 | error = XFS_ERROR(EEXIST); |
| 441 | goto error_return; | 433 | goto error_return; |
| @@ -451,12 +443,11 @@ xfs_rename( | |||
| 451 | * In case there is already an entry with the same | 443 | * In case there is already an entry with the same |
| 452 | * name at the destination directory, remove it first. | 444 | * name at the destination directory, remove it first. |
| 453 | */ | 445 | */ |
| 454 | error = XFS_DIR_REPLACE(mp, tp, target_dp, target_name, | 446 | error = xfs_dir_replace(tp, target_dp, target_name, |
| 455 | target_namelen, src_ip->i_ino, &first_block, | 447 | target_namelen, src_ip->i_ino, |
| 456 | &free_list, spaceres); | 448 | &first_block, &free_list, spaceres); |
| 457 | if (error) { | 449 | if (error) |
| 458 | goto abort_return; | 450 | goto abort_return; |
| 459 | } | ||
| 460 | xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 451 | xfs_ichgtime(target_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
| 461 | 452 | ||
| 462 | /* | 453 | /* |
| @@ -464,9 +455,8 @@ xfs_rename( | |||
| 464 | * dir no longer points to it. | 455 | * dir no longer points to it. |
| 465 | */ | 456 | */ |
| 466 | error = xfs_droplink(tp, target_ip); | 457 | error = xfs_droplink(tp, target_ip); |
| 467 | if (error) { | 458 | if (error) |
| 468 | goto abort_return; | 459 | goto abort_return; |
| 469 | } | ||
| 470 | target_ip_dropped = 1; | 460 | target_ip_dropped = 1; |
| 471 | 461 | ||
| 472 | if (src_is_directory) { | 462 | if (src_is_directory) { |
| @@ -474,9 +464,8 @@ xfs_rename( | |||
| 474 | * Drop the link from the old "." entry. | 464 | * Drop the link from the old "." entry. |
| 475 | */ | 465 | */ |
| 476 | error = xfs_droplink(tp, target_ip); | 466 | error = xfs_droplink(tp, target_ip); |
| 477 | if (error) { | 467 | if (error) |
| 478 | goto abort_return; | 468 | goto abort_return; |
| 479 | } | ||
| 480 | } | 469 | } |
| 481 | 470 | ||
| 482 | /* Do this test while we still hold the locks */ | 471 | /* Do this test while we still hold the locks */ |
| @@ -488,18 +477,15 @@ xfs_rename( | |||
| 488 | * Remove the source. | 477 | * Remove the source. |
| 489 | */ | 478 | */ |
| 490 | if (new_parent && src_is_directory) { | 479 | if (new_parent && src_is_directory) { |
| 491 | |||
| 492 | /* | 480 | /* |
| 493 | * Rewrite the ".." entry to point to the new | 481 | * Rewrite the ".." entry to point to the new |
| 494 | * directory. | 482 | * directory. |
| 495 | */ | 483 | */ |
| 496 | error = XFS_DIR_REPLACE(mp, tp, src_ip, "..", 2, | 484 | error = xfs_dir_replace(tp, src_ip, "..", 2, target_dp->i_ino, |
| 497 | target_dp->i_ino, &first_block, | 485 | &first_block, &free_list, spaceres); |
| 498 | &free_list, spaceres); | ||
| 499 | ASSERT(error != EEXIST); | 486 | ASSERT(error != EEXIST); |
| 500 | if (error) { | 487 | if (error) |
| 501 | goto abort_return; | 488 | goto abort_return; |
| 502 | } | ||
| 503 | xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 489 | xfs_ichgtime(src_ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
| 504 | 490 | ||
| 505 | } else { | 491 | } else { |
| @@ -527,16 +513,14 @@ xfs_rename( | |||
| 527 | * entry that's moved no longer points to it. | 513 | * entry that's moved no longer points to it. |
| 528 | */ | 514 | */ |
| 529 | error = xfs_droplink(tp, src_dp); | 515 | error = xfs_droplink(tp, src_dp); |
| 530 | if (error) { | 516 | if (error) |
| 531 | goto abort_return; | 517 | goto abort_return; |
| 532 | } | ||
| 533 | } | 518 | } |
| 534 | 519 | ||
| 535 | error = XFS_DIR_REMOVENAME(mp, tp, src_dp, src_name, src_namelen, | 520 | error = xfs_dir_removename(tp, src_dp, src_name, src_namelen, |
| 536 | src_ip->i_ino, &first_block, &free_list, spaceres); | 521 | src_ip->i_ino, &first_block, &free_list, spaceres); |
| 537 | if (error) { | 522 | if (error) |
| 538 | goto abort_return; | 523 | goto abort_return; |
| 539 | } | ||
| 540 | xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 524 | xfs_ichgtime(src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
| 541 | 525 | ||
| 542 | /* | 526 | /* |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index af290cf37ac1..0c1e42b037ef 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.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" |
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c index c55e28189aba..defb2febaaf5 100644 --- a/fs/xfs/xfs_rw.c +++ b/fs/xfs/xfs_rw.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" |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 39f0b1ed3224..ee2721e0de4d 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
| @@ -24,7 +24,6 @@ | |||
| 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" |
| @@ -33,7 +32,6 @@ | |||
| 33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
| 34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
| 35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
| 36 | #include "xfs_dir_sf.h" | ||
| 37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
| 38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
| 39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 100d9a4b38ee..cb65c3a603f5 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
| @@ -805,12 +805,9 @@ typedef struct xfs_trans { | |||
| 805 | ((mp)->m_sb.sb_inodesize + \ | 805 | ((mp)->m_sb.sb_inodesize + \ |
| 806 | (mp)->m_sb.sb_sectsize * 2 + \ | 806 | (mp)->m_sb.sb_sectsize * 2 + \ |
| 807 | (mp)->m_dirblksize + \ | 807 | (mp)->m_dirblksize + \ |
| 808 | (XFS_DIR_IS_V1(mp) ? 0 : \ | 808 | XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \ |
| 809 | XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1))) + \ | ||
| 810 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ | 809 | XFS_ALLOCFREE_LOG_RES(mp, 1) + \ |
| 811 | (128 * (4 + \ | 810 | (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ |
| 812 | (XFS_DIR_IS_V1(mp) ? 0 : \ | ||
| 813 | XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \ | ||
| 814 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) | 811 | XFS_ALLOCFREE_LOG_COUNT(mp, 1)))) |
| 815 | 812 | ||
| 816 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) | 813 | #define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork) |
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index e1ca7b6fde42..558c87ff0c41 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dmapi.h" | 25 | #include "xfs_dmapi.h" |
| 27 | #include "xfs_mount.h" | 26 | #include "xfs_mount.h" |
| 28 | #include "xfs_trans_priv.h" | 27 | #include "xfs_trans_priv.h" |
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 8cedd1583bc8..60b6b898022b 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.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" |
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index 7d7d627f25df..b290270dd4a6 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include "xfs_inum.h" | 22 | #include "xfs_inum.h" |
| 23 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
| 24 | #include "xfs_sb.h" | 24 | #include "xfs_sb.h" |
| 25 | #include "xfs_dir.h" | ||
| 26 | #include "xfs_dmapi.h" | 25 | #include "xfs_dmapi.h" |
| 27 | #include "xfs_mount.h" | 26 | #include "xfs_mount.h" |
| 28 | #include "xfs_trans_priv.h" | 27 | #include "xfs_trans_priv.h" |
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 7c5894d59f81..b8db1d5cde5a 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.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" |
diff --git a/fs/xfs/xfs_trans_space.h b/fs/xfs/xfs_trans_space.h index 7fe3792b18df..4ea2e5074bdd 100644 --- a/fs/xfs/xfs_trans_space.h +++ b/fs/xfs/xfs_trans_space.h | |||
| @@ -30,8 +30,7 @@ | |||
| 30 | XFS_EXTENTADD_SPACE_RES(mp,w)) | 30 | XFS_EXTENTADD_SPACE_RES(mp,w)) |
| 31 | #define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) | 31 | #define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) |
| 32 | #define XFS_DAENTER_DBS(mp,w) \ | 32 | #define XFS_DAENTER_DBS(mp,w) \ |
| 33 | (XFS_DA_NODE_MAXDEPTH + \ | 33 | (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0)) |
| 34 | ((XFS_DIR_IS_V2(mp) && (w) == XFS_DATA_FORK) ? 2 : 0)) | ||
| 35 | #define XFS_DAENTER_BLOCKS(mp,w) \ | 34 | #define XFS_DAENTER_BLOCKS(mp,w) \ |
| 36 | (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w)) | 35 | (XFS_DAENTER_1B(mp,w) * XFS_DAENTER_DBS(mp,w)) |
| 37 | #define XFS_DAENTER_BMAP1B(mp,w) \ | 36 | #define XFS_DAENTER_BMAP1B(mp,w) \ |
| @@ -41,10 +40,7 @@ | |||
| 41 | #define XFS_DAENTER_SPACE_RES(mp,w) \ | 40 | #define XFS_DAENTER_SPACE_RES(mp,w) \ |
| 42 | (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w)) | 41 | (XFS_DAENTER_BLOCKS(mp,w) + XFS_DAENTER_BMAPS(mp,w)) |
| 43 | #define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w) | 42 | #define XFS_DAREMOVE_SPACE_RES(mp,w) XFS_DAENTER_BMAPS(mp,w) |
| 44 | #define XFS_DIRENTER_MAX_SPLIT(mp,nl) \ | 43 | #define XFS_DIRENTER_MAX_SPLIT(mp,nl) 1 |
| 45 | (((mp)->m_sb.sb_blocksize == 512 && \ | ||
| 46 | XFS_DIR_IS_V1(mp) && \ | ||
| 47 | (nl) >= XFS_DIR_LEAF_CAN_DOUBLE_SPLIT_LEN) ? 2 : 1) | ||
| 48 | #define XFS_DIRENTER_SPACE_RES(mp,nl) \ | 44 | #define XFS_DIRENTER_SPACE_RES(mp,nl) \ |
| 49 | (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \ | 45 | (XFS_DAENTER_SPACE_RES(mp, XFS_DATA_FORK) * \ |
| 50 | XFS_DIRENTER_MAX_SPLIT(mp,nl)) | 46 | XFS_DIRENTER_MAX_SPLIT(mp,nl)) |
| @@ -57,8 +53,7 @@ | |||
| 57 | * Space reservation values for various transactions. | 53 | * Space reservation values for various transactions. |
| 58 | */ | 54 | */ |
| 59 | #define XFS_ADDAFORK_SPACE_RES(mp) \ | 55 | #define XFS_ADDAFORK_SPACE_RES(mp) \ |
| 60 | ((mp)->m_dirblkfsbs + \ | 56 | ((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)) |
| 61 | (XFS_DIR_IS_V1(mp) ? 0 : XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))) | ||
| 62 | #define XFS_ATTRRM_SPACE_RES(mp) \ | 57 | #define XFS_ATTRRM_SPACE_RES(mp) \ |
| 63 | XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) | 58 | XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) |
| 64 | /* This macro is not used - see inline code in xfs_attr_set */ | 59 | /* This macro is not used - see inline code in xfs_attr_set */ |
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 37fdc2dc00b4..9014d7e44488 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
| @@ -24,12 +24,10 @@ | |||
| 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_dir_sf.h" | ||
| 33 | #include "xfs_dir2_sf.h" | 31 | #include "xfs_dir2_sf.h" |
| 34 | #include "xfs_attr_sf.h" | 32 | #include "xfs_attr_sf.h" |
| 35 | #include "xfs_dinode.h" | 33 | #include "xfs_dinode.h" |
| @@ -82,8 +80,7 @@ xfs_dir_lookup_int( | |||
| 82 | 80 | ||
| 83 | dp = XFS_BHVTOI(dir_bdp); | 81 | dp = XFS_BHVTOI(dir_bdp); |
| 84 | 82 | ||
| 85 | error = XFS_DIR_LOOKUP(dp->i_mount, NULL, dp, | 83 | error = xfs_dir_lookup(NULL, dp, VNAME(dentry), VNAMELEN(dentry), inum); |
| 86 | VNAME(dentry), VNAMELEN(dentry), inum); | ||
| 87 | if (!error) { | 84 | if (!error) { |
| 88 | /* | 85 | /* |
| 89 | * Unlock the directory. We do this because we can't | 86 | * Unlock the directory. We do this because we can't |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 918531b64787..6c96391f3f1a 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
| @@ -24,7 +24,6 @@ | |||
| 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" |
| @@ -32,7 +31,6 @@ | |||
| 32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
| 33 | #include "xfs_ialloc_btree.h" | 32 | #include "xfs_ialloc_btree.h" |
| 34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
| 35 | #include "xfs_dir_sf.h" | ||
| 36 | #include "xfs_dir2_sf.h" | 34 | #include "xfs_dir2_sf.h" |
| 37 | #include "xfs_attr_sf.h" | 35 | #include "xfs_attr_sf.h" |
| 38 | #include "xfs_dinode.h" | 36 | #include "xfs_dinode.h" |
| @@ -131,9 +129,6 @@ xfs_init(void) | |||
| 131 | #ifdef XFS_BMBT_TRACE | 129 | #ifdef XFS_BMBT_TRACE |
| 132 | xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP); | 130 | xfs_bmbt_trace_buf = ktrace_alloc(XFS_BMBT_TRACE_SIZE, KM_SLEEP); |
| 133 | #endif | 131 | #endif |
| 134 | #ifdef XFS_DIR_TRACE | ||
| 135 | xfs_dir_trace_buf = ktrace_alloc(XFS_DIR_TRACE_SIZE, KM_SLEEP); | ||
| 136 | #endif | ||
| 137 | #ifdef XFS_ATTR_TRACE | 132 | #ifdef XFS_ATTR_TRACE |
| 138 | xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP); | 133 | xfs_attr_trace_buf = ktrace_alloc(XFS_ATTR_TRACE_SIZE, KM_SLEEP); |
| 139 | #endif | 134 | #endif |
| @@ -177,9 +172,6 @@ xfs_cleanup(void) | |||
| 177 | #ifdef XFS_ATTR_TRACE | 172 | #ifdef XFS_ATTR_TRACE |
| 178 | ktrace_free(xfs_attr_trace_buf); | 173 | ktrace_free(xfs_attr_trace_buf); |
| 179 | #endif | 174 | #endif |
| 180 | #ifdef XFS_DIR_TRACE | ||
| 181 | ktrace_free(xfs_dir_trace_buf); | ||
| 182 | #endif | ||
| 183 | #ifdef XFS_BMBT_TRACE | 175 | #ifdef XFS_BMBT_TRACE |
| 184 | ktrace_free(xfs_bmbt_trace_buf); | 176 | ktrace_free(xfs_bmbt_trace_buf); |
| 185 | #endif | 177 | #endif |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 26d96d1b25cd..00a6b7dc24a0 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
| 26 | #include "xfs_sb.h" | 26 | #include "xfs_sb.h" |
| 27 | #include "xfs_ag.h" | 27 | #include "xfs_ag.h" |
| 28 | #include "xfs_dir.h" | ||
| 29 | #include "xfs_dir2.h" | 28 | #include "xfs_dir2.h" |
| 30 | #include "xfs_dmapi.h" | 29 | #include "xfs_dmapi.h" |
| 31 | #include "xfs_mount.h" | 30 | #include "xfs_mount.h" |
| @@ -33,13 +32,11 @@ | |||
| 33 | #include "xfs_bmap_btree.h" | 32 | #include "xfs_bmap_btree.h" |
| 34 | #include "xfs_alloc_btree.h" | 33 | #include "xfs_alloc_btree.h" |
| 35 | #include "xfs_ialloc_btree.h" | 34 | #include "xfs_ialloc_btree.h" |
| 36 | #include "xfs_dir_sf.h" | ||
| 37 | #include "xfs_dir2_sf.h" | 35 | #include "xfs_dir2_sf.h" |
| 38 | #include "xfs_attr_sf.h" | 36 | #include "xfs_attr_sf.h" |
| 39 | #include "xfs_dinode.h" | 37 | #include "xfs_dinode.h" |
| 40 | #include "xfs_inode.h" | 38 | #include "xfs_inode.h" |
| 41 | #include "xfs_inode_item.h" | 39 | #include "xfs_inode_item.h" |
| 42 | #include "xfs_dir_leaf.h" | ||
| 43 | #include "xfs_itable.h" | 40 | #include "xfs_itable.h" |
| 44 | #include "xfs_btree.h" | 41 | #include "xfs_btree.h" |
| 45 | #include "xfs_ialloc.h" | 42 | #include "xfs_ialloc.h" |
| @@ -1958,8 +1955,7 @@ xfs_create( | |||
| 1958 | if (error) | 1955 | if (error) |
| 1959 | goto error_return; | 1956 | goto error_return; |
| 1960 | 1957 | ||
| 1961 | if (resblks == 0 && | 1958 | if (resblks == 0 && (error = xfs_dir_canenter(tp, dp, name, namelen))) |
| 1962 | (error = XFS_DIR_CANENTER(mp, tp, dp, name, namelen))) | ||
| 1963 | goto error_return; | 1959 | goto error_return; |
| 1964 | rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; | 1960 | rdev = (vap->va_mask & XFS_AT_RDEV) ? vap->va_rdev : 0; |
| 1965 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, | 1961 | error = xfs_dir_ialloc(&tp, dp, vap->va_mode, 1, |
| @@ -1990,9 +1986,9 @@ xfs_create( | |||
| 1990 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | 1986 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); |
| 1991 | dp_joined_to_trans = B_TRUE; | 1987 | dp_joined_to_trans = B_TRUE; |
| 1992 | 1988 | ||
| 1993 | error = XFS_DIR_CREATENAME(mp, tp, dp, name, namelen, ip->i_ino, | 1989 | error = xfs_dir_createname(tp, dp, name, namelen, ip->i_ino, |
| 1994 | &first_block, &free_list, | 1990 | &first_block, &free_list, resblks ? |
| 1995 | resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); | 1991 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); |
| 1996 | if (error) { | 1992 | if (error) { |
| 1997 | ASSERT(error != ENOSPC); | 1993 | ASSERT(error != ENOSPC); |
| 1998 | goto abort_return; | 1994 | goto abort_return; |
| @@ -2468,8 +2464,8 @@ xfs_remove( | |||
| 2468 | * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. | 2464 | * Entry must exist since we did a lookup in xfs_lock_dir_and_entry. |
| 2469 | */ | 2465 | */ |
| 2470 | XFS_BMAP_INIT(&free_list, &first_block); | 2466 | XFS_BMAP_INIT(&free_list, &first_block); |
| 2471 | error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, ip->i_ino, | 2467 | error = xfs_dir_removename(tp, dp, name, namelen, ip->i_ino, |
| 2472 | &first_block, &free_list, 0); | 2468 | &first_block, &free_list, 0); |
| 2473 | if (error) { | 2469 | if (error) { |
| 2474 | ASSERT(error != ENOENT); | 2470 | ASSERT(error != ENOENT); |
| 2475 | REMOVE_DEBUG_TRACE(__LINE__); | 2471 | REMOVE_DEBUG_TRACE(__LINE__); |
| @@ -2688,13 +2684,12 @@ xfs_link( | |||
| 2688 | } | 2684 | } |
| 2689 | 2685 | ||
| 2690 | if (resblks == 0 && | 2686 | if (resblks == 0 && |
| 2691 | (error = XFS_DIR_CANENTER(mp, tp, tdp, target_name, | 2687 | (error = xfs_dir_canenter(tp, tdp, target_name, target_namelen))) |
| 2692 | target_namelen))) | ||
| 2693 | goto error_return; | 2688 | goto error_return; |
| 2694 | 2689 | ||
| 2695 | XFS_BMAP_INIT(&free_list, &first_block); | 2690 | XFS_BMAP_INIT(&free_list, &first_block); |
| 2696 | 2691 | ||
| 2697 | error = XFS_DIR_CREATENAME(mp, tp, tdp, target_name, target_namelen, | 2692 | error = xfs_dir_createname(tp, tdp, target_name, target_namelen, |
| 2698 | sip->i_ino, &first_block, &free_list, | 2693 | sip->i_ino, &first_block, &free_list, |
| 2699 | resblks); | 2694 | resblks); |
| 2700 | if (error) | 2695 | if (error) |
| @@ -2860,7 +2855,7 @@ xfs_mkdir( | |||
| 2860 | goto error_return; | 2855 | goto error_return; |
| 2861 | 2856 | ||
| 2862 | if (resblks == 0 && | 2857 | if (resblks == 0 && |
| 2863 | (error = XFS_DIR_CANENTER(mp, tp, dp, dir_name, dir_namelen))) | 2858 | (error = xfs_dir_canenter(tp, dp, dir_name, dir_namelen))) |
| 2864 | goto error_return; | 2859 | goto error_return; |
| 2865 | /* | 2860 | /* |
| 2866 | * create the directory inode. | 2861 | * create the directory inode. |
| @@ -2887,9 +2882,9 @@ xfs_mkdir( | |||
| 2887 | 2882 | ||
| 2888 | XFS_BMAP_INIT(&free_list, &first_block); | 2883 | XFS_BMAP_INIT(&free_list, &first_block); |
| 2889 | 2884 | ||
| 2890 | error = XFS_DIR_CREATENAME(mp, tp, dp, dir_name, dir_namelen, | 2885 | error = xfs_dir_createname(tp, dp, dir_name, dir_namelen, cdp->i_ino, |
| 2891 | cdp->i_ino, &first_block, &free_list, | 2886 | &first_block, &free_list, resblks ? |
| 2892 | resblks ? resblks - XFS_IALLOC_SPACE_RES(mp) : 0); | 2887 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); |
| 2893 | if (error) { | 2888 | if (error) { |
| 2894 | ASSERT(error != ENOSPC); | 2889 | ASSERT(error != ENOSPC); |
| 2895 | goto error1; | 2890 | goto error1; |
| @@ -2903,16 +2898,14 @@ xfs_mkdir( | |||
| 2903 | */ | 2898 | */ |
| 2904 | dp->i_gen++; | 2899 | dp->i_gen++; |
| 2905 | 2900 | ||
| 2906 | error = XFS_DIR_INIT(mp, tp, cdp, dp); | 2901 | error = xfs_dir_init(tp, cdp, dp); |
| 2907 | if (error) { | 2902 | if (error) |
| 2908 | goto error2; | 2903 | goto error2; |
| 2909 | } | ||
| 2910 | 2904 | ||
| 2911 | cdp->i_gen = 1; | 2905 | cdp->i_gen = 1; |
| 2912 | error = xfs_bumplink(tp, dp); | 2906 | error = xfs_bumplink(tp, dp); |
| 2913 | if (error) { | 2907 | if (error) |
| 2914 | goto error2; | 2908 | goto error2; |
| 2915 | } | ||
| 2916 | 2909 | ||
| 2917 | cvp = XFS_ITOV(cdp); | 2910 | cvp = XFS_ITOV(cdp); |
| 2918 | 2911 | ||
| @@ -3121,16 +3114,15 @@ xfs_rmdir( | |||
| 3121 | error = XFS_ERROR(ENOTEMPTY); | 3114 | error = XFS_ERROR(ENOTEMPTY); |
| 3122 | goto error_return; | 3115 | goto error_return; |
| 3123 | } | 3116 | } |
| 3124 | if (!XFS_DIR_ISEMPTY(mp, cdp)) { | 3117 | if (!xfs_dir_isempty(cdp)) { |
| 3125 | error = XFS_ERROR(ENOTEMPTY); | 3118 | error = XFS_ERROR(ENOTEMPTY); |
| 3126 | goto error_return; | 3119 | goto error_return; |
| 3127 | } | 3120 | } |
| 3128 | 3121 | ||
| 3129 | error = XFS_DIR_REMOVENAME(mp, tp, dp, name, namelen, cdp->i_ino, | 3122 | error = xfs_dir_removename(tp, dp, name, namelen, cdp->i_ino, |
| 3130 | &first_block, &free_list, resblks); | 3123 | &first_block, &free_list, resblks); |
| 3131 | if (error) { | 3124 | if (error) |
| 3132 | goto error1; | 3125 | goto error1; |
| 3133 | } | ||
| 3134 | 3126 | ||
| 3135 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 3127 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
| 3136 | 3128 | ||
| @@ -3229,8 +3221,6 @@ xfs_rmdir( | |||
| 3229 | 3221 | ||
| 3230 | 3222 | ||
| 3231 | /* | 3223 | /* |
| 3232 | * xfs_readdir | ||
| 3233 | * | ||
| 3234 | * Read dp's entries starting at uiop->uio_offset and translate them into | 3224 | * Read dp's entries starting at uiop->uio_offset and translate them into |
| 3235 | * bufsize bytes worth of struct dirents starting at bufbase. | 3225 | * bufsize bytes worth of struct dirents starting at bufbase. |
| 3236 | */ | 3226 | */ |
| @@ -3250,21 +3240,16 @@ xfs_readdir( | |||
| 3250 | (inst_t *)__return_address); | 3240 | (inst_t *)__return_address); |
| 3251 | dp = XFS_BHVTOI(dir_bdp); | 3241 | dp = XFS_BHVTOI(dir_bdp); |
| 3252 | 3242 | ||
| 3253 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) { | 3243 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) |
| 3254 | return XFS_ERROR(EIO); | 3244 | return XFS_ERROR(EIO); |
| 3255 | } | ||
| 3256 | 3245 | ||
| 3257 | lock_mode = xfs_ilock_map_shared(dp); | 3246 | lock_mode = xfs_ilock_map_shared(dp); |
| 3258 | error = XFS_DIR_GETDENTS(dp->i_mount, tp, dp, uiop, eofp); | 3247 | error = xfs_dir_getdents(tp, dp, uiop, eofp); |
| 3259 | xfs_iunlock_map_shared(dp, lock_mode); | 3248 | xfs_iunlock_map_shared(dp, lock_mode); |
| 3260 | return error; | 3249 | return error; |
| 3261 | } | 3250 | } |
| 3262 | 3251 | ||
| 3263 | 3252 | ||
| 3264 | /* | ||
| 3265 | * xfs_symlink | ||
| 3266 | * | ||
| 3267 | */ | ||
| 3268 | STATIC int | 3253 | STATIC int |
| 3269 | xfs_symlink( | 3254 | xfs_symlink( |
| 3270 | bhv_desc_t *dir_bdp, | 3255 | bhv_desc_t *dir_bdp, |
| @@ -3328,7 +3313,7 @@ xfs_symlink( | |||
| 3328 | int len, total; | 3313 | int len, total; |
| 3329 | char *path; | 3314 | char *path; |
| 3330 | 3315 | ||
| 3331 | for(total = 0, path = target_path; total < pathlen;) { | 3316 | for (total = 0, path = target_path; total < pathlen;) { |
| 3332 | /* | 3317 | /* |
| 3333 | * Skip any slashes. | 3318 | * Skip any slashes. |
| 3334 | */ | 3319 | */ |
| @@ -3422,7 +3407,7 @@ xfs_symlink( | |||
| 3422 | * Check for ability to enter directory entry, if no space reserved. | 3407 | * Check for ability to enter directory entry, if no space reserved. |
| 3423 | */ | 3408 | */ |
| 3424 | if (resblks == 0 && | 3409 | if (resblks == 0 && |
| 3425 | (error = XFS_DIR_CANENTER(mp, tp, dp, link_name, link_namelen))) | 3410 | (error = xfs_dir_canenter(tp, dp, link_name, link_namelen))) |
| 3426 | goto error_return; | 3411 | goto error_return; |
| 3427 | /* | 3412 | /* |
| 3428 | * Initialize the bmap freelist prior to calling either | 3413 | * Initialize the bmap freelist prior to calling either |
| @@ -3509,11 +3494,10 @@ xfs_symlink( | |||
| 3509 | /* | 3494 | /* |
| 3510 | * Create the directory entry for the symlink. | 3495 | * Create the directory entry for the symlink. |
| 3511 | */ | 3496 | */ |
| 3512 | error = XFS_DIR_CREATENAME(mp, tp, dp, link_name, link_namelen, | 3497 | error = xfs_dir_createname(tp, dp, link_name, link_namelen, ip->i_ino, |
| 3513 | ip->i_ino, &first_block, &free_list, resblks); | 3498 | &first_block, &free_list, resblks); |
| 3514 | if (error) { | 3499 | if (error) |
| 3515 | goto error1; | 3500 | goto error1; |
| 3516 | } | ||
| 3517 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | 3501 | xfs_ichgtime(dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
| 3518 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | 3502 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); |
| 3519 | 3503 | ||
