aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2016-07-19 21:54:59 -0400
committerDave Chinner <david@fromorbit.com>2016-07-19 21:54:59 -0400
commitdc4113d2433e01b06685743552d99573c9d470f3 (patch)
tree7962a56c283c90f8415f01e8f04d61495ce6cd7d
parentb47ec80bfe1eadd530a13522890d43d71eda10f8 (diff)
parentaa2dd0ad4d6d7dd85bb13ed64b872803be046f96 (diff)
Merge branch 'xfs-4.8-dir2-sf-fixes' into for-next
-rw-r--r--fs/xfs/libxfs/xfs_da_format.c31
-rw-r--r--fs/xfs/libxfs/xfs_da_format.h43
-rw-r--r--fs/xfs/libxfs/xfs_dir2_sf.c38
-rw-r--r--fs/xfs/xfs_linux.h7
-rw-r--r--fs/xfs/xfs_ondisk.h4
5 files changed, 37 insertions, 86 deletions
diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c
index 9d624a622946..f1e8d4dbb600 100644
--- a/fs/xfs/libxfs/xfs_da_format.c
+++ b/fs/xfs/libxfs/xfs_da_format.c
@@ -40,8 +40,7 @@ xfs_dir2_sf_entsize(
40 int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ 40 int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */
41 41
42 count += len; /* name */ 42 count += len; /* name */
43 count += hdr->i8count ? sizeof(xfs_dir2_ino8_t) : 43 count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */
44 sizeof(xfs_dir2_ino4_t); /* ino # */
45 return count; 44 return count;
46} 45}
47 46
@@ -125,33 +124,33 @@ xfs_dir3_sfe_put_ftype(
125static xfs_ino_t 124static xfs_ino_t
126xfs_dir2_sf_get_ino( 125xfs_dir2_sf_get_ino(
127 struct xfs_dir2_sf_hdr *hdr, 126 struct xfs_dir2_sf_hdr *hdr,
128 xfs_dir2_inou_t *from) 127 __uint8_t *from)
129{ 128{
130 if (hdr->i8count) 129 if (hdr->i8count)
131 return get_unaligned_be64(&from->i8.i) & 0x00ffffffffffffffULL; 130 return get_unaligned_be64(from) & 0x00ffffffffffffffULL;
132 else 131 else
133 return get_unaligned_be32(&from->i4.i); 132 return get_unaligned_be32(from);
134} 133}
135 134
136static void 135static void
137xfs_dir2_sf_put_ino( 136xfs_dir2_sf_put_ino(
138 struct xfs_dir2_sf_hdr *hdr, 137 struct xfs_dir2_sf_hdr *hdr,
139 xfs_dir2_inou_t *to, 138 __uint8_t *to,
140 xfs_ino_t ino) 139 xfs_ino_t ino)
141{ 140{
142 ASSERT((ino & 0xff00000000000000ULL) == 0); 141 ASSERT((ino & 0xff00000000000000ULL) == 0);
143 142
144 if (hdr->i8count) 143 if (hdr->i8count)
145 put_unaligned_be64(ino, &to->i8.i); 144 put_unaligned_be64(ino, to);
146 else 145 else
147 put_unaligned_be32(ino, &to->i4.i); 146 put_unaligned_be32(ino, to);
148} 147}
149 148
150static xfs_ino_t 149static xfs_ino_t
151xfs_dir2_sf_get_parent_ino( 150xfs_dir2_sf_get_parent_ino(
152 struct xfs_dir2_sf_hdr *hdr) 151 struct xfs_dir2_sf_hdr *hdr)
153{ 152{
154 return xfs_dir2_sf_get_ino(hdr, &hdr->parent); 153 return xfs_dir2_sf_get_ino(hdr, hdr->parent);
155} 154}
156 155
157static void 156static void
@@ -159,7 +158,7 @@ xfs_dir2_sf_put_parent_ino(
159 struct xfs_dir2_sf_hdr *hdr, 158 struct xfs_dir2_sf_hdr *hdr,
160 xfs_ino_t ino) 159 xfs_ino_t ino)
161{ 160{
162 xfs_dir2_sf_put_ino(hdr, &hdr->parent, ino); 161 xfs_dir2_sf_put_ino(hdr, hdr->parent, ino);
163} 162}
164 163
165/* 164/*
@@ -173,8 +172,7 @@ xfs_dir2_sfe_get_ino(
173 struct xfs_dir2_sf_hdr *hdr, 172 struct xfs_dir2_sf_hdr *hdr,
174 struct xfs_dir2_sf_entry *sfep) 173 struct xfs_dir2_sf_entry *sfep)
175{ 174{
176 return xfs_dir2_sf_get_ino(hdr, 175 return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen]);
177 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen]);
178} 176}
179 177
180static void 178static void
@@ -183,8 +181,7 @@ xfs_dir2_sfe_put_ino(
183 struct xfs_dir2_sf_entry *sfep, 181 struct xfs_dir2_sf_entry *sfep,
184 xfs_ino_t ino) 182 xfs_ino_t ino)
185{ 183{
186 xfs_dir2_sf_put_ino(hdr, 184 xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen], ino);
187 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen], ino);
188} 185}
189 186
190static xfs_ino_t 187static xfs_ino_t
@@ -192,8 +189,7 @@ xfs_dir3_sfe_get_ino(
192 struct xfs_dir2_sf_hdr *hdr, 189 struct xfs_dir2_sf_hdr *hdr,
193 struct xfs_dir2_sf_entry *sfep) 190 struct xfs_dir2_sf_entry *sfep)
194{ 191{
195 return xfs_dir2_sf_get_ino(hdr, 192 return xfs_dir2_sf_get_ino(hdr, &sfep->name[sfep->namelen + 1]);
196 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1]);
197} 193}
198 194
199static void 195static void
@@ -202,8 +198,7 @@ xfs_dir3_sfe_put_ino(
202 struct xfs_dir2_sf_entry *sfep, 198 struct xfs_dir2_sf_entry *sfep,
203 xfs_ino_t ino) 199 xfs_ino_t ino)
204{ 200{
205 xfs_dir2_sf_put_ino(hdr, 201 xfs_dir2_sf_put_ino(hdr, &sfep->name[sfep->namelen + 1], ino);
206 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1], ino);
207} 202}
208 203
209 204
diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h
index 8d4d8bce41bf..685f23b67056 100644
--- a/fs/xfs/libxfs/xfs_da_format.h
+++ b/fs/xfs/libxfs/xfs_da_format.h
@@ -192,12 +192,6 @@ typedef __uint16_t xfs_dir2_data_off_t;
192typedef uint xfs_dir2_data_aoff_t; /* argument form */ 192typedef uint xfs_dir2_data_aoff_t; /* argument form */
193 193
194/* 194/*
195 * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
196 * Only need 16 bits, this is the byte offset into the single block form.
197 */
198typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
199
200/*
201 * Offset in data space of a data entry. 195 * Offset in data space of a data entry.
202 */ 196 */
203typedef __uint32_t xfs_dir2_dataptr_t; 197typedef __uint32_t xfs_dir2_dataptr_t;
@@ -214,22 +208,10 @@ typedef xfs_off_t xfs_dir2_off_t;
214 */ 208 */
215typedef __uint32_t xfs_dir2_db_t; 209typedef __uint32_t xfs_dir2_db_t;
216 210
217/* 211#define XFS_INO32_SIZE 4
218 * Inode number stored as 8 8-bit values. 212#define XFS_INO64_SIZE 8
219 */ 213#define XFS_INO64_DIFF (XFS_INO64_SIZE - XFS_INO32_SIZE)
220typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
221
222/*
223 * Inode number stored as 4 8-bit values.
224 * Works a lot of the time, when all the inode numbers in a directory
225 * fit in 32 bits.
226 */
227typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
228 214
229typedef union {
230 xfs_dir2_ino8_t i8;
231 xfs_dir2_ino4_t i4;
232} xfs_dir2_inou_t;
233#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL) 215#define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
234 216
235/* 217/*
@@ -246,39 +228,38 @@ typedef union {
246typedef struct xfs_dir2_sf_hdr { 228typedef struct xfs_dir2_sf_hdr {
247 __uint8_t count; /* count of entries */ 229 __uint8_t count; /* count of entries */
248 __uint8_t i8count; /* count of 8-byte inode #s */ 230 __uint8_t i8count; /* count of 8-byte inode #s */
249 xfs_dir2_inou_t parent; /* parent dir inode number */ 231 __uint8_t parent[8]; /* parent dir inode number */
250} __arch_pack xfs_dir2_sf_hdr_t; 232} __packed xfs_dir2_sf_hdr_t;
251 233
252typedef struct xfs_dir2_sf_entry { 234typedef struct xfs_dir2_sf_entry {
253 __u8 namelen; /* actual name length */ 235 __u8 namelen; /* actual name length */
254 xfs_dir2_sf_off_t offset; /* saved offset */ 236 __u8 offset[2]; /* saved offset */
255 __u8 name[]; /* name, variable size */ 237 __u8 name[]; /* name, variable size */
256 /* 238 /*
257 * A single byte containing the file type field follows the inode 239 * A single byte containing the file type field follows the inode
258 * number for version 3 directory entries. 240 * number for version 3 directory entries.
259 * 241 *
260 * A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a 242 * A 64-bit or 32-bit inode number follows here, at a variable offset
261 * variable offset after the name. 243 * after the name.
262 */ 244 */
263} __arch_pack xfs_dir2_sf_entry_t; 245} xfs_dir2_sf_entry_t;
264 246
265static inline int xfs_dir2_sf_hdr_size(int i8count) 247static inline int xfs_dir2_sf_hdr_size(int i8count)
266{ 248{
267 return sizeof(struct xfs_dir2_sf_hdr) - 249 return sizeof(struct xfs_dir2_sf_hdr) -
268 (i8count == 0) * 250 (i8count == 0) * XFS_INO64_DIFF;
269 (sizeof(xfs_dir2_ino8_t) - sizeof(xfs_dir2_ino4_t));
270} 251}
271 252
272static inline xfs_dir2_data_aoff_t 253static inline xfs_dir2_data_aoff_t
273xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) 254xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
274{ 255{
275 return get_unaligned_be16(&sfep->offset.i); 256 return get_unaligned_be16(sfep->offset);
276} 257}
277 258
278static inline void 259static inline void
279xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) 260xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
280{ 261{
281 put_unaligned_be16(off, &sfep->offset.i); 262 put_unaligned_be16(off, sfep->offset);
282} 263}
283 264
284static inline struct xfs_dir2_sf_entry * 265static inline struct xfs_dir2_sf_entry *
diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c
index e5bb9cc3b243..c6809ff41197 100644
--- a/fs/xfs/libxfs/xfs_dir2_sf.c
+++ b/fs/xfs/libxfs/xfs_dir2_sf.c
@@ -126,13 +126,12 @@ xfs_dir2_block_sfsize(
126 /* 126 /*
127 * Calculate the new size, see if we should give up yet. 127 * Calculate the new size, see if we should give up yet.
128 */ 128 */
129 size = xfs_dir2_sf_hdr_size(i8count) + /* header */ 129 size = xfs_dir2_sf_hdr_size(i8count) + /* header */
130 count + /* namelen */ 130 count * 3 * sizeof(u8) + /* namelen + offset */
131 count * (uint)sizeof(xfs_dir2_sf_off_t) + /* offset */ 131 namelen + /* name */
132 namelen + /* name */ 132 (i8count ? /* inumber */
133 (i8count ? /* inumber */ 133 count * XFS_INO64_SIZE :
134 (uint)sizeof(xfs_dir2_ino8_t) * count : 134 count * XFS_INO32_SIZE);
135 (uint)sizeof(xfs_dir2_ino4_t) * count);
136 if (size > XFS_IFORK_DSIZE(dp)) 135 if (size > XFS_IFORK_DSIZE(dp))
137 return size; /* size value is a failure */ 136 return size; /* size value is a failure */
138 } 137 }
@@ -319,10 +318,7 @@ xfs_dir2_sf_addname(
319 /* 318 /*
320 * Yes, adjust the inode size. old count + (parent + new) 319 * Yes, adjust the inode size. old count + (parent + new)
321 */ 320 */
322 incr_isize += 321 incr_isize += (sfp->count + 2) * XFS_INO64_DIFF;
323 (sfp->count + 2) *
324 ((uint)sizeof(xfs_dir2_ino8_t) -
325 (uint)sizeof(xfs_dir2_ino4_t));
326 objchange = 1; 322 objchange = 1;
327 } 323 }
328 324
@@ -897,11 +893,7 @@ xfs_dir2_sf_replace(
897 int error; /* error return value */ 893 int error; /* error return value */
898 int newsize; /* new inode size */ 894 int newsize; /* new inode size */
899 895
900 newsize = 896 newsize = dp->i_df.if_bytes + (sfp->count + 1) * XFS_INO64_DIFF;
901 dp->i_df.if_bytes +
902 (sfp->count + 1) *
903 ((uint)sizeof(xfs_dir2_ino8_t) -
904 (uint)sizeof(xfs_dir2_ino4_t));
905 /* 897 /*
906 * Won't fit as shortform, convert to block then do replace. 898 * Won't fit as shortform, convert to block then do replace.
907 */ 899 */
@@ -1022,10 +1014,7 @@ xfs_dir2_sf_toino4(
1022 /* 1014 /*
1023 * Compute the new inode size. 1015 * Compute the new inode size.
1024 */ 1016 */
1025 newsize = 1017 newsize = oldsize - (oldsfp->count + 1) * XFS_INO64_DIFF;
1026 oldsize -
1027 (oldsfp->count + 1) *
1028 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t));
1029 xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); 1018 xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK);
1030 xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); 1019 xfs_idata_realloc(dp, newsize, XFS_DATA_FORK);
1031 /* 1020 /*
@@ -1048,7 +1037,7 @@ xfs_dir2_sf_toino4(
1048 i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), 1037 i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep),
1049 oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { 1038 oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) {
1050 sfep->namelen = oldsfep->namelen; 1039 sfep->namelen = oldsfep->namelen;
1051 sfep->offset = oldsfep->offset; 1040 memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
1052 memcpy(sfep->name, oldsfep->name, sfep->namelen); 1041 memcpy(sfep->name, oldsfep->name, sfep->namelen);
1053 dp->d_ops->sf_put_ino(sfp, sfep, 1042 dp->d_ops->sf_put_ino(sfp, sfep,
1054 dp->d_ops->sf_get_ino(oldsfp, oldsfep)); 1043 dp->d_ops->sf_get_ino(oldsfp, oldsfep));
@@ -1098,10 +1087,7 @@ xfs_dir2_sf_toino8(
1098 /* 1087 /*
1099 * Compute the new inode size (nb: entry count + 1 for parent) 1088 * Compute the new inode size (nb: entry count + 1 for parent)
1100 */ 1089 */
1101 newsize = 1090 newsize = oldsize + (oldsfp->count + 1) * XFS_INO64_DIFF;
1102 oldsize +
1103 (oldsfp->count + 1) *
1104 ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t));
1105 xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); 1091 xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK);
1106 xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); 1092 xfs_idata_realloc(dp, newsize, XFS_DATA_FORK);
1107 /* 1093 /*
@@ -1124,7 +1110,7 @@ xfs_dir2_sf_toino8(
1124 i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), 1110 i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep),
1125 oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { 1111 oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) {
1126 sfep->namelen = oldsfep->namelen; 1112 sfep->namelen = oldsfep->namelen;
1127 sfep->offset = oldsfep->offset; 1113 memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset));
1128 memcpy(sfep->name, oldsfep->name, sfep->namelen); 1114 memcpy(sfep->name, oldsfep->name, sfep->namelen);
1129 dp->d_ops->sf_put_ino(sfp, sfep, 1115 dp->d_ops->sf_put_ino(sfp, sfep,
1130 dp->d_ops->sf_get_ino(oldsfp, oldsfep)); 1116 dp->d_ops->sf_get_ino(oldsfp, oldsfep));
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index a8192dc797dc..b8d64d520e12 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -328,13 +328,6 @@ static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y)
328 return x; 328 return x;
329} 329}
330 330
331/* ARM old ABI has some weird alignment/padding */
332#if defined(__arm__) && !defined(__ARM_EABI__)
333#define __arch_pack __attribute__((packed))
334#else
335#define __arch_pack
336#endif
337
338#define ASSERT_ALWAYS(expr) \ 331#define ASSERT_ALWAYS(expr) \
339 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 332 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
340 333
diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h
index 17ec0248f771..0cc8d8f74356 100644
--- a/fs/xfs/xfs_ondisk.h
+++ b/fs/xfs/xfs_ondisk.h
@@ -106,9 +106,6 @@ xfs_check_ondisk_structs(void)
106 XFS_CHECK_OFFSET(xfs_dir2_data_unused_t, length, 2); 106 XFS_CHECK_OFFSET(xfs_dir2_data_unused_t, length, 2);
107 XFS_CHECK_STRUCT_SIZE(xfs_dir2_free_hdr_t, 16); 107 XFS_CHECK_STRUCT_SIZE(xfs_dir2_free_hdr_t, 16);
108 XFS_CHECK_STRUCT_SIZE(xfs_dir2_free_t, 16); 108 XFS_CHECK_STRUCT_SIZE(xfs_dir2_free_t, 16);
109 XFS_CHECK_STRUCT_SIZE(xfs_dir2_ino4_t, 4);
110 XFS_CHECK_STRUCT_SIZE(xfs_dir2_ino8_t, 8);
111 XFS_CHECK_STRUCT_SIZE(xfs_dir2_inou_t, 8);
112 XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_entry_t, 8); 109 XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_entry_t, 8);
113 XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_hdr_t, 16); 110 XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_hdr_t, 16);
114 XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_t, 16); 111 XFS_CHECK_STRUCT_SIZE(xfs_dir2_leaf_t, 16);
@@ -118,7 +115,6 @@ xfs_check_ondisk_structs(void)
118 XFS_CHECK_OFFSET(xfs_dir2_sf_entry_t, offset, 1); 115 XFS_CHECK_OFFSET(xfs_dir2_sf_entry_t, offset, 1);
119 XFS_CHECK_OFFSET(xfs_dir2_sf_entry_t, name, 3); 116 XFS_CHECK_OFFSET(xfs_dir2_sf_entry_t, name, 3);
120 XFS_CHECK_STRUCT_SIZE(xfs_dir2_sf_hdr_t, 10); 117 XFS_CHECK_STRUCT_SIZE(xfs_dir2_sf_hdr_t, 10);
121 XFS_CHECK_STRUCT_SIZE(xfs_dir2_sf_off_t, 2);
122 118
123 /* log structures */ 119 /* log structures */
124 XFS_CHECK_STRUCT_SIZE(struct xfs_dq_logformat, 24); 120 XFS_CHECK_STRUCT_SIZE(struct xfs_dq_logformat, 24);