aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_sf.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2011-07-08 08:35:03 -0400
committerChristoph Hellwig <hch@lst.de>2011-07-08 08:35:03 -0400
commit8bc387875870c87087f138741f456983cbc54660 (patch)
treee121ad0f46dc72517172b0fd9b21603504b6a117 /fs/xfs/xfs_dir2_sf.c
parent4fb44c8272a071290d2ad76164c532fa2902b604 (diff)
xfs: cleanup shortform directory inode number handling
Refactor the shortform directory helpers that deal with the 32-bit vs 64-bit wide inode numbers into more sensible helpers, and kill the xfs_intino_t typedef that is now superflous. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Alex Elder <aelder@sgi.com> Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_dir2_sf.c')
-rw-r--r--fs/xfs/xfs_dir2_sf.c138
1 files changed, 99 insertions, 39 deletions
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index b1bae6b1eed..4c3ecf2c739 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -59,6 +59,79 @@ static void xfs_dir2_sf_toino4(xfs_da_args_t *args);
59static void xfs_dir2_sf_toino8(xfs_da_args_t *args); 59static void xfs_dir2_sf_toino8(xfs_da_args_t *args);
60#endif /* XFS_BIG_INUMS */ 60#endif /* XFS_BIG_INUMS */
61 61
62
63/*
64 * Inode numbers in short-form directories can come in two versions,
65 * either 4 bytes or 8 bytes wide. These helpers deal with the
66 * two forms transparently by looking at the headers i8count field.
67 */
68static xfs_ino_t
69xfs_dir2_sf_get_ino(
70 struct xfs_dir2_sf *sfp,
71 xfs_dir2_inou_t *from)
72{
73 if (sfp->hdr.i8count)
74 return XFS_GET_DIR_INO8(from->i8);
75 else
76 return XFS_GET_DIR_INO4(from->i4);
77}
78
79static void
80xfs_dir2_sf_put_ino(
81 struct xfs_dir2_sf *sfp,
82 xfs_dir2_inou_t *to,
83 xfs_ino_t ino)
84{
85 if (sfp->hdr.i8count)
86 XFS_PUT_DIR_INO8(ino, to->i8);
87 else
88 XFS_PUT_DIR_INO4(ino, to->i4);
89}
90
91xfs_ino_t
92xfs_dir2_sf_get_parent_ino(
93 struct xfs_dir2_sf *sfp)
94{
95 return xfs_dir2_sf_get_ino(sfp, &sfp->hdr.parent);
96}
97
98static void
99xfs_dir2_sf_put_parent_ino(
100 struct xfs_dir2_sf *sfp,
101 xfs_ino_t ino)
102{
103 xfs_dir2_sf_put_ino(sfp, &sfp->hdr.parent, ino);
104}
105
106/*
107 * In short-form directory entries the inode numbers are stored at variable
108 * offset behind the entry name. The inode numbers may only be accessed
109 * through the helpers below.
110 */
111static xfs_dir2_inou_t *
112xfs_dir2_sfe_inop(
113 struct xfs_dir2_sf_entry *sfep)
114{
115 return (xfs_dir2_inou_t *)&sfep->name[sfep->namelen];
116}
117
118xfs_ino_t
119xfs_dir2_sfe_get_ino(
120 struct xfs_dir2_sf *sfp,
121 struct xfs_dir2_sf_entry *sfep)
122{
123 return xfs_dir2_sf_get_ino(sfp, xfs_dir2_sfe_inop(sfep));
124}
125
126static void
127xfs_dir2_sfe_put_ino(
128 struct xfs_dir2_sf *sfp,
129 struct xfs_dir2_sf_entry *sfep,
130 xfs_ino_t ino)
131{
132 xfs_dir2_sf_put_ino(sfp, xfs_dir2_sfe_inop(sfep), ino);
133}
134
62/* 135/*
63 * Given a block directory (dp/block), calculate its size as a shortform (sf) 136 * Given a block directory (dp/block), calculate its size as a shortform (sf)
64 * directory and a header for the sf directory, if it will fit it the 137 * directory and a header for the sf directory, if it will fit it the
@@ -138,7 +211,7 @@ xfs_dir2_block_sfsize(
138 */ 211 */
139 sfhp->count = count; 212 sfhp->count = count;
140 sfhp->i8count = i8count; 213 sfhp->i8count = i8count;
141 xfs_dir2_sf_put_inumber((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent); 214 xfs_dir2_sf_put_parent_ino((xfs_dir2_sf_t *)sfhp, parent);
142 return size; 215 return size;
143} 216}
144 217
@@ -165,7 +238,6 @@ xfs_dir2_block_to_sf(
165 char *ptr; /* current data pointer */ 238 char *ptr; /* current data pointer */
166 xfs_dir2_sf_entry_t *sfep; /* shortform entry */ 239 xfs_dir2_sf_entry_t *sfep; /* shortform entry */
167 xfs_dir2_sf_t *sfp; /* shortform structure */ 240 xfs_dir2_sf_t *sfp; /* shortform structure */
168 xfs_ino_t temp;
169 241
170 trace_xfs_dir2_block_to_sf(args); 242 trace_xfs_dir2_block_to_sf(args);
171 243
@@ -233,7 +305,7 @@ xfs_dir2_block_to_sf(
233 else if (dep->namelen == 2 && 305 else if (dep->namelen == 2 &&
234 dep->name[0] == '.' && dep->name[1] == '.') 306 dep->name[0] == '.' && dep->name[1] == '.')
235 ASSERT(be64_to_cpu(dep->inumber) == 307 ASSERT(be64_to_cpu(dep->inumber) ==
236 xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); 308 xfs_dir2_sf_get_parent_ino(sfp));
237 /* 309 /*
238 * Normal entry, copy it into shortform. 310 * Normal entry, copy it into shortform.
239 */ 311 */
@@ -243,9 +315,9 @@ xfs_dir2_block_to_sf(
243 (xfs_dir2_data_aoff_t) 315 (xfs_dir2_data_aoff_t)
244 ((char *)dep - (char *)block)); 316 ((char *)dep - (char *)block));
245 memcpy(sfep->name, dep->name, dep->namelen); 317 memcpy(sfep->name, dep->name, dep->namelen);
246 temp = be64_to_cpu(dep->inumber); 318 xfs_dir2_sfe_put_ino(sfp, sfep,
247 xfs_dir2_sf_put_inumber(sfp, &temp, 319 be64_to_cpu(dep->inumber));
248 xfs_dir2_sf_inumberp(sfep)); 320
249 sfep = xfs_dir2_sf_nextentry(sfp, sfep); 321 sfep = xfs_dir2_sf_nextentry(sfp, sfep);
250 } 322 }
251 ptr += xfs_dir2_data_entsize(dep->namelen); 323 ptr += xfs_dir2_data_entsize(dep->namelen);
@@ -406,8 +478,7 @@ xfs_dir2_sf_addname_easy(
406 sfep->namelen = args->namelen; 478 sfep->namelen = args->namelen;
407 xfs_dir2_sf_put_offset(sfep, offset); 479 xfs_dir2_sf_put_offset(sfep, offset);
408 memcpy(sfep->name, args->name, sfep->namelen); 480 memcpy(sfep->name, args->name, sfep->namelen);
409 xfs_dir2_sf_put_inumber(sfp, &args->inumber, 481 xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber);
410 xfs_dir2_sf_inumberp(sfep));
411 /* 482 /*
412 * Update the header and inode. 483 * Update the header and inode.
413 */ 484 */
@@ -498,8 +569,7 @@ xfs_dir2_sf_addname_hard(
498 sfep->namelen = args->namelen; 569 sfep->namelen = args->namelen;
499 xfs_dir2_sf_put_offset(sfep, offset); 570 xfs_dir2_sf_put_offset(sfep, offset);
500 memcpy(sfep->name, args->name, sfep->namelen); 571 memcpy(sfep->name, args->name, sfep->namelen);
501 xfs_dir2_sf_put_inumber(sfp, &args->inumber, 572 xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber);
502 xfs_dir2_sf_inumberp(sfep));
503 sfp->hdr.count++; 573 sfp->hdr.count++;
504#if XFS_BIG_INUMS 574#if XFS_BIG_INUMS
505 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) 575 if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange)
@@ -618,14 +688,14 @@ xfs_dir2_sf_check(
618 688
619 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; 689 sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data;
620 offset = XFS_DIR2_DATA_FIRST_OFFSET; 690 offset = XFS_DIR2_DATA_FIRST_OFFSET;
621 ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); 691 ino = xfs_dir2_sf_get_parent_ino(sfp);
622 i8count = ino > XFS_DIR2_MAX_SHORT_INUM; 692 i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
623 693
624 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); 694 for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp);
625 i < sfp->hdr.count; 695 i < sfp->hdr.count;
626 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { 696 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
627 ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); 697 ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset);
628 ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); 698 ino = xfs_dir2_sfe_get_ino(sfp, sfep);
629 i8count += ino > XFS_DIR2_MAX_SHORT_INUM; 699 i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
630 offset = 700 offset =
631 xfs_dir2_sf_get_offset(sfep) + 701 xfs_dir2_sf_get_offset(sfep) +
@@ -686,7 +756,7 @@ xfs_dir2_sf_create(
686 /* 756 /*
687 * Now can put in the inode number, since i8count is set. 757 * Now can put in the inode number, since i8count is set.
688 */ 758 */
689 xfs_dir2_sf_put_inumber(sfp, &pino, &sfp->hdr.parent); 759 xfs_dir2_sf_put_parent_ino(sfp, pino);
690 sfp->hdr.count = 0; 760 sfp->hdr.count = 0;
691 dp->i_d.di_size = size; 761 dp->i_d.di_size = size;
692 xfs_dir2_sf_check(args); 762 xfs_dir2_sf_check(args);
@@ -759,7 +829,7 @@ xfs_dir2_sf_getdents(
759 * Put .. entry unless we're starting past it. 829 * Put .. entry unless we're starting past it.
760 */ 830 */
761 if (*offset <= dotdot_offset) { 831 if (*offset <= dotdot_offset) {
762 ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); 832 ino = xfs_dir2_sf_get_parent_ino(sfp);
763 if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) { 833 if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) {
764 *offset = dotdot_offset & 0x7fffffff; 834 *offset = dotdot_offset & 0x7fffffff;
765 return 0; 835 return 0;
@@ -779,7 +849,7 @@ xfs_dir2_sf_getdents(
779 continue; 849 continue;
780 } 850 }
781 851
782 ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); 852 ino = xfs_dir2_sfe_get_ino(sfp, sfep);
783 if (filldir(dirent, (char *)sfep->name, sfep->namelen, 853 if (filldir(dirent, (char *)sfep->name, sfep->namelen,
784 off & 0x7fffffff, ino, DT_UNKNOWN)) { 854 off & 0x7fffffff, ino, DT_UNKNOWN)) {
785 *offset = off & 0x7fffffff; 855 *offset = off & 0x7fffffff;
@@ -839,7 +909,7 @@ xfs_dir2_sf_lookup(
839 */ 909 */
840 if (args->namelen == 2 && 910 if (args->namelen == 2 &&
841 args->name[0] == '.' && args->name[1] == '.') { 911 args->name[0] == '.' && args->name[1] == '.') {
842 args->inumber = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); 912 args->inumber = xfs_dir2_sf_get_parent_ino(sfp);
843 args->cmpresult = XFS_CMP_EXACT; 913 args->cmpresult = XFS_CMP_EXACT;
844 return XFS_ERROR(EEXIST); 914 return XFS_ERROR(EEXIST);
845 } 915 }
@@ -858,8 +928,7 @@ xfs_dir2_sf_lookup(
858 sfep->namelen); 928 sfep->namelen);
859 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { 929 if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
860 args->cmpresult = cmp; 930 args->cmpresult = cmp;
861 args->inumber = xfs_dir2_sf_get_inumber(sfp, 931 args->inumber = xfs_dir2_sfe_get_ino(sfp, sfep);
862 xfs_dir2_sf_inumberp(sfep));
863 if (cmp == XFS_CMP_EXACT) 932 if (cmp == XFS_CMP_EXACT)
864 return XFS_ERROR(EEXIST); 933 return XFS_ERROR(EEXIST);
865 ci_sfep = sfep; 934 ci_sfep = sfep;
@@ -918,9 +987,8 @@ xfs_dir2_sf_removename(
918 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { 987 i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) {
919 if (xfs_da_compname(args, sfep->name, sfep->namelen) == 988 if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
920 XFS_CMP_EXACT) { 989 XFS_CMP_EXACT) {
921 ASSERT(xfs_dir2_sf_get_inumber(sfp, 990 ASSERT(xfs_dir2_sfe_get_ino(sfp, sfep) ==
922 xfs_dir2_sf_inumberp(sfep)) == 991 args->inumber);
923 args->inumber);
924 break; 992 break;
925 } 993 }
926 } 994 }
@@ -1040,10 +1108,10 @@ xfs_dir2_sf_replace(
1040 if (args->namelen == 2 && 1108 if (args->namelen == 2 &&
1041 args->name[0] == '.' && args->name[1] == '.') { 1109 args->name[0] == '.' && args->name[1] == '.') {
1042#if XFS_BIG_INUMS || defined(DEBUG) 1110#if XFS_BIG_INUMS || defined(DEBUG)
1043 ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); 1111 ino = xfs_dir2_sf_get_parent_ino(sfp);
1044 ASSERT(args->inumber != ino); 1112 ASSERT(args->inumber != ino);
1045#endif 1113#endif
1046 xfs_dir2_sf_put_inumber(sfp, &args->inumber, &sfp->hdr.parent); 1114 xfs_dir2_sf_put_parent_ino(sfp, args->inumber);
1047 } 1115 }
1048 /* 1116 /*
1049 * Normal entry, look for the name. 1117 * Normal entry, look for the name.
@@ -1055,12 +1123,10 @@ xfs_dir2_sf_replace(
1055 if (xfs_da_compname(args, sfep->name, sfep->namelen) == 1123 if (xfs_da_compname(args, sfep->name, sfep->namelen) ==
1056 XFS_CMP_EXACT) { 1124 XFS_CMP_EXACT) {
1057#if XFS_BIG_INUMS || defined(DEBUG) 1125#if XFS_BIG_INUMS || defined(DEBUG)
1058 ino = xfs_dir2_sf_get_inumber(sfp, 1126 ino = xfs_dir2_sfe_get_ino(sfp, sfep);
1059 xfs_dir2_sf_inumberp(sfep));
1060 ASSERT(args->inumber != ino); 1127 ASSERT(args->inumber != ino);
1061#endif 1128#endif
1062 xfs_dir2_sf_put_inumber(sfp, &args->inumber, 1129 xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber);
1063 xfs_dir2_sf_inumberp(sfep));
1064 break; 1130 break;
1065 } 1131 }
1066 } 1132 }
@@ -1121,7 +1187,6 @@ xfs_dir2_sf_toino4(
1121 char *buf; /* old dir's buffer */ 1187 char *buf; /* old dir's buffer */
1122 xfs_inode_t *dp; /* incore directory inode */ 1188 xfs_inode_t *dp; /* incore directory inode */
1123 int i; /* entry index */ 1189 int i; /* entry index */
1124 xfs_ino_t ino; /* entry inode number */
1125 int newsize; /* new inode size */ 1190 int newsize; /* new inode size */
1126 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ 1191 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */
1127 xfs_dir2_sf_t *oldsfp; /* old sf directory */ 1192 xfs_dir2_sf_t *oldsfp; /* old sf directory */
@@ -1162,8 +1227,7 @@ xfs_dir2_sf_toino4(
1162 */ 1227 */
1163 sfp->hdr.count = oldsfp->hdr.count; 1228 sfp->hdr.count = oldsfp->hdr.count;
1164 sfp->hdr.i8count = 0; 1229 sfp->hdr.i8count = 0;
1165 ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); 1230 xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
1166 xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent);
1167 /* 1231 /*
1168 * Copy the entries field by field. 1232 * Copy the entries field by field.
1169 */ 1233 */
@@ -1175,9 +1239,8 @@ xfs_dir2_sf_toino4(
1175 sfep->namelen = oldsfep->namelen; 1239 sfep->namelen = oldsfep->namelen;
1176 sfep->offset = oldsfep->offset; 1240 sfep->offset = oldsfep->offset;
1177 memcpy(sfep->name, oldsfep->name, sfep->namelen); 1241 memcpy(sfep->name, oldsfep->name, sfep->namelen);
1178 ino = xfs_dir2_sf_get_inumber(oldsfp, 1242 xfs_dir2_sfe_put_ino(sfp, sfep,
1179 xfs_dir2_sf_inumberp(oldsfep)); 1243 xfs_dir2_sfe_get_ino(oldsfp, oldsfep));
1180 xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep));
1181 } 1244 }
1182 /* 1245 /*
1183 * Clean up the inode. 1246 * Clean up the inode.
@@ -1199,7 +1262,6 @@ xfs_dir2_sf_toino8(
1199 char *buf; /* old dir's buffer */ 1262 char *buf; /* old dir's buffer */
1200 xfs_inode_t *dp; /* incore directory inode */ 1263 xfs_inode_t *dp; /* incore directory inode */
1201 int i; /* entry index */ 1264 int i; /* entry index */
1202 xfs_ino_t ino; /* entry inode number */
1203 int newsize; /* new inode size */ 1265 int newsize; /* new inode size */
1204 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ 1266 xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */
1205 xfs_dir2_sf_t *oldsfp; /* old sf directory */ 1267 xfs_dir2_sf_t *oldsfp; /* old sf directory */
@@ -1240,8 +1302,7 @@ xfs_dir2_sf_toino8(
1240 */ 1302 */
1241 sfp->hdr.count = oldsfp->hdr.count; 1303 sfp->hdr.count = oldsfp->hdr.count;
1242 sfp->hdr.i8count = 1; 1304 sfp->hdr.i8count = 1;
1243 ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); 1305 xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp));
1244 xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent);
1245 /* 1306 /*
1246 * Copy the entries field by field. 1307 * Copy the entries field by field.
1247 */ 1308 */
@@ -1253,9 +1314,8 @@ xfs_dir2_sf_toino8(
1253 sfep->namelen = oldsfep->namelen; 1314 sfep->namelen = oldsfep->namelen;
1254 sfep->offset = oldsfep->offset; 1315 sfep->offset = oldsfep->offset;
1255 memcpy(sfep->name, oldsfep->name, sfep->namelen); 1316 memcpy(sfep->name, oldsfep->name, sfep->namelen);
1256 ino = xfs_dir2_sf_get_inumber(oldsfp, 1317 xfs_dir2_sfe_put_ino(sfp, sfep,
1257 xfs_dir2_sf_inumberp(oldsfep)); 1318 xfs_dir2_sfe_get_ino(oldsfp, oldsfep));
1258 xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep));
1259 } 1319 }
1260 /* 1320 /*
1261 * Clean up the inode. 1321 * Clean up the inode.