aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-10-29 07:11:48 -0400
committerBen Myers <bpm@sgi.com>2013-10-30 14:39:14 -0400
commit9d23fc8575de7012b8853bd6fefe10534665de2f (patch)
tree6dab547e4e967349aaa48bca5d64e0055a32508d /fs
parent4740175e75f70ab71f76ae98ab00f7db731a48f7 (diff)
xfs: vectorise directory data operations
Following from the initial patches to vectorise the shortform directory encode/decode operations, convert half the data block operations to use the vector. The rest will be done in a second patch. This further reduces the size of the built binary: text data bss dec hex filename 794490 96802 1096 892388 d9de4 fs/xfs/xfs.o.orig 792986 96802 1096 890884 d9804 fs/xfs/xfs.o.p1 792350 96802 1096 890248 d9588 fs/xfs/xfs.o.p2 789293 96802 1096 887191 d8997 fs/xfs/xfs.o.p3 Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_da_format.c218
-rw-r--r--fs/xfs/xfs_da_format.h123
-rw-r--r--fs/xfs/xfs_dir2.h22
-rw-r--r--fs/xfs/xfs_dir2_block.c54
-rw-r--r--fs/xfs/xfs_dir2_data.c38
-rw-r--r--fs/xfs/xfs_dir2_leaf.c22
-rw-r--r--fs/xfs/xfs_dir2_node.c23
-rw-r--r--fs/xfs/xfs_dir2_readdir.c14
-rw-r--r--fs/xfs/xfs_dir2_sf.c20
9 files changed, 329 insertions, 205 deletions
diff --git a/fs/xfs/xfs_da_format.c b/fs/xfs/xfs_da_format.c
index 62f55a0186ae..d0285fdfb6e7 100644
--- a/fs/xfs/xfs_da_format.c
+++ b/fs/xfs/xfs_da_format.c
@@ -28,7 +28,9 @@
28#include "xfs_inode.h" 28#include "xfs_inode.h"
29#include "xfs_dir2.h" 29#include "xfs_dir2.h"
30 30
31 31/*
32 * Shortform directory ops
33 */
32static int 34static int
33xfs_dir2_sf_entsize( 35xfs_dir2_sf_entsize(
34 struct xfs_dir2_sf_hdr *hdr, 36 struct xfs_dir2_sf_hdr *hdr,
@@ -203,6 +205,184 @@ xfs_dir3_sfe_put_ino(
203 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1], ino); 205 (xfs_dir2_inou_t *)&sfep->name[sfep->namelen + 1], ino);
204} 206}
205 207
208
209/*
210 * Directory data block operations
211 */
212static int
213__xfs_dir3_data_entsize(
214 bool ftype,
215 int n)
216{
217 int size = offsetof(struct xfs_dir2_data_entry, name[0]);
218
219 size += n;
220 size += sizeof(xfs_dir2_data_off_t);
221 if (ftype)
222 size += sizeof(__uint8_t);
223 return roundup(size, XFS_DIR2_DATA_ALIGN);
224}
225
226static int
227xfs_dir2_data_entsize(
228 int n)
229{
230 return __xfs_dir3_data_entsize(false, n);
231}
232static int
233xfs_dir3_data_entsize(
234 int n)
235{
236 return __xfs_dir3_data_entsize(true, n);
237}
238
239static __uint8_t
240xfs_dir2_data_get_ftype(
241 struct xfs_dir2_data_entry *dep)
242{
243 return XFS_DIR3_FT_UNKNOWN;
244}
245
246static void
247xfs_dir2_data_put_ftype(
248 struct xfs_dir2_data_entry *dep,
249 __uint8_t ftype)
250{
251 ASSERT(ftype < XFS_DIR3_FT_MAX);
252}
253
254static __uint8_t
255xfs_dir3_data_get_ftype(
256 struct xfs_dir2_data_entry *dep)
257{
258 __uint8_t ftype = dep->name[dep->namelen];
259
260 ASSERT(ftype < XFS_DIR3_FT_MAX);
261 if (ftype >= XFS_DIR3_FT_MAX)
262 return XFS_DIR3_FT_UNKNOWN;
263 return ftype;
264}
265
266static void
267xfs_dir3_data_put_ftype(
268 struct xfs_dir2_data_entry *dep,
269 __uint8_t type)
270{
271 ASSERT(type < XFS_DIR3_FT_MAX);
272 ASSERT(dep->namelen != 0);
273
274 dep->name[dep->namelen] = type;
275}
276
277/*
278 * Pointer to an entry's tag word.
279 */
280static __be16 *
281xfs_dir2_data_entry_tag_p(
282 struct xfs_dir2_data_entry *dep)
283{
284 return (__be16 *)((char *)dep +
285 xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
286}
287
288static __be16 *
289xfs_dir3_data_entry_tag_p(
290 struct xfs_dir2_data_entry *dep)
291{
292 return (__be16 *)((char *)dep +
293 xfs_dir3_data_entsize(dep->namelen) - sizeof(__be16));
294}
295
296/*
297 * Offsets of . and .. in data space (always block 0)
298 */
299static xfs_dir2_data_aoff_t
300xfs_dir2_data_dot_offset(void)
301{
302 return sizeof(struct xfs_dir2_data_hdr);
303}
304
305static xfs_dir2_data_aoff_t
306xfs_dir2_data_dotdot_offset(void)
307{
308 return xfs_dir2_data_dot_offset() + xfs_dir2_data_entsize(1);
309}
310
311static xfs_dir2_data_aoff_t
312xfs_dir2_data_first_offset(void)
313{
314 return xfs_dir2_data_dotdot_offset() + xfs_dir2_data_entsize(2);
315}
316
317static xfs_dir2_data_aoff_t
318xfs_dir3_data_dot_offset(void)
319{
320 return sizeof(struct xfs_dir3_data_hdr);
321}
322
323static xfs_dir2_data_aoff_t
324xfs_dir3_data_dotdot_offset(void)
325{
326 return xfs_dir3_data_dot_offset() + xfs_dir3_data_entsize(1);
327}
328
329static xfs_dir2_data_aoff_t
330xfs_dir3_data_first_offset(void)
331{
332 return xfs_dir3_data_dotdot_offset() + xfs_dir3_data_entsize(2);
333}
334
335/*
336 * location of . and .. in data space (always block 0)
337 */
338static struct xfs_dir2_data_entry *
339xfs_dir2_data_dot_entry_p(
340 struct xfs_dir2_data_hdr *hdr)
341{
342 return (struct xfs_dir2_data_entry *)
343 ((char *)hdr + xfs_dir2_data_dot_offset());
344}
345
346static struct xfs_dir2_data_entry *
347xfs_dir2_data_dotdot_entry_p(
348 struct xfs_dir2_data_hdr *hdr)
349{
350 return (struct xfs_dir2_data_entry *)
351 ((char *)hdr + xfs_dir2_data_dotdot_offset());
352}
353
354static struct xfs_dir2_data_entry *
355xfs_dir2_data_first_entry_p(
356 struct xfs_dir2_data_hdr *hdr)
357{
358 return (struct xfs_dir2_data_entry *)
359 ((char *)hdr + xfs_dir2_data_first_offset());
360}
361
362static struct xfs_dir2_data_entry *
363xfs_dir3_data_dot_entry_p(
364 struct xfs_dir2_data_hdr *hdr)
365{
366 return (struct xfs_dir2_data_entry *)
367 ((char *)hdr + xfs_dir3_data_dot_offset());
368}
369
370static struct xfs_dir2_data_entry *
371xfs_dir3_data_dotdot_entry_p(
372 struct xfs_dir2_data_hdr *hdr)
373{
374 return (struct xfs_dir2_data_entry *)
375 ((char *)hdr + xfs_dir3_data_dotdot_offset());
376}
377
378static struct xfs_dir2_data_entry *
379xfs_dir3_data_first_entry_p(
380 struct xfs_dir2_data_hdr *hdr)
381{
382 return (struct xfs_dir2_data_entry *)
383 ((char *)hdr + xfs_dir3_data_first_offset());
384}
385
206const struct xfs_dir_ops xfs_dir2_ops = { 386const struct xfs_dir_ops xfs_dir2_ops = {
207 .sf_entsize = xfs_dir2_sf_entsize, 387 .sf_entsize = xfs_dir2_sf_entsize,
208 .sf_nextentry = xfs_dir2_sf_nextentry, 388 .sf_nextentry = xfs_dir2_sf_nextentry,
@@ -212,6 +392,18 @@ const struct xfs_dir_ops xfs_dir2_ops = {
212 .sf_put_ino = xfs_dir2_sfe_put_ino, 392 .sf_put_ino = xfs_dir2_sfe_put_ino,
213 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, 393 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
214 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, 394 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
395
396 .data_entsize = xfs_dir2_data_entsize,
397 .data_get_ftype = xfs_dir2_data_get_ftype,
398 .data_put_ftype = xfs_dir2_data_put_ftype,
399 .data_entry_tag_p = xfs_dir2_data_entry_tag_p,
400
401 .data_dot_offset = xfs_dir2_data_dot_offset,
402 .data_dotdot_offset = xfs_dir2_data_dotdot_offset,
403 .data_first_offset = xfs_dir2_data_first_offset,
404 .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
405 .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p,
406 .data_first_entry_p = xfs_dir2_data_first_entry_p,
215}; 407};
216 408
217const struct xfs_dir_ops xfs_dir2_ftype_ops = { 409const struct xfs_dir_ops xfs_dir2_ftype_ops = {
@@ -223,6 +415,18 @@ const struct xfs_dir_ops xfs_dir2_ftype_ops = {
223 .sf_put_ino = xfs_dir3_sfe_put_ino, 415 .sf_put_ino = xfs_dir3_sfe_put_ino,
224 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, 416 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
225 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, 417 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
418
419 .data_entsize = xfs_dir3_data_entsize,
420 .data_get_ftype = xfs_dir3_data_get_ftype,
421 .data_put_ftype = xfs_dir3_data_put_ftype,
422 .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
423
424 .data_dot_offset = xfs_dir2_data_dot_offset,
425 .data_dotdot_offset = xfs_dir2_data_dotdot_offset,
426 .data_first_offset = xfs_dir2_data_first_offset,
427 .data_dot_entry_p = xfs_dir2_data_dot_entry_p,
428 .data_dotdot_entry_p = xfs_dir2_data_dotdot_entry_p,
429 .data_first_entry_p = xfs_dir2_data_first_entry_p,
226}; 430};
227 431
228const struct xfs_dir_ops xfs_dir3_ops = { 432const struct xfs_dir_ops xfs_dir3_ops = {
@@ -234,4 +438,16 @@ const struct xfs_dir_ops xfs_dir3_ops = {
234 .sf_put_ino = xfs_dir3_sfe_put_ino, 438 .sf_put_ino = xfs_dir3_sfe_put_ino,
235 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino, 439 .sf_get_parent_ino = xfs_dir2_sf_get_parent_ino,
236 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino, 440 .sf_put_parent_ino = xfs_dir2_sf_put_parent_ino,
441
442 .data_entsize = xfs_dir3_data_entsize,
443 .data_get_ftype = xfs_dir3_data_get_ftype,
444 .data_put_ftype = xfs_dir3_data_put_ftype,
445 .data_entry_tag_p = xfs_dir3_data_entry_tag_p,
446
447 .data_dot_offset = xfs_dir3_data_dot_offset,
448 .data_dotdot_offset = xfs_dir3_data_dotdot_offset,
449 .data_first_offset = xfs_dir3_data_first_offset,
450 .data_dot_entry_p = xfs_dir3_data_dot_entry_p,
451 .data_dotdot_entry_p = xfs_dir3_data_dotdot_entry_p,
452 .data_first_entry_p = xfs_dir3_data_first_entry_p,
237}; 453};
diff --git a/fs/xfs/xfs_da_format.h b/fs/xfs/xfs_da_format.h
index 68c2ad5ba54f..5b72dd2f8a69 100644
--- a/fs/xfs/xfs_da_format.h
+++ b/fs/xfs/xfs_da_format.h
@@ -456,72 +456,6 @@ typedef struct xfs_dir2_data_unused {
456} xfs_dir2_data_unused_t; 456} xfs_dir2_data_unused_t;
457 457
458/* 458/*
459 * Size of a data entry.
460 */
461static inline int
462__xfs_dir3_data_entsize(
463 bool ftype,
464 int n)
465{
466 int size = offsetof(struct xfs_dir2_data_entry, name[0]);
467
468 size += n;
469 size += sizeof(xfs_dir2_data_off_t);
470 if (ftype)
471 size += sizeof(__uint8_t);
472 return roundup(size, XFS_DIR2_DATA_ALIGN);
473}
474static inline int
475xfs_dir3_data_entsize(
476 struct xfs_mount *mp,
477 int n)
478{
479 bool ftype = xfs_sb_version_hasftype(&mp->m_sb) ? true : false;
480 return __xfs_dir3_data_entsize(ftype, n);
481}
482
483static inline __uint8_t
484xfs_dir3_dirent_get_ftype(
485 struct xfs_mount *mp,
486 struct xfs_dir2_data_entry *dep)
487{
488 if (xfs_sb_version_hasftype(&mp->m_sb)) {
489 __uint8_t type = dep->name[dep->namelen];
490
491 ASSERT(type < XFS_DIR3_FT_MAX);
492 if (type < XFS_DIR3_FT_MAX)
493 return type;
494
495 }
496 return XFS_DIR3_FT_UNKNOWN;
497}
498
499static inline void
500xfs_dir3_dirent_put_ftype(
501 struct xfs_mount *mp,
502 struct xfs_dir2_data_entry *dep,
503 __uint8_t type)
504{
505 ASSERT(type < XFS_DIR3_FT_MAX);
506 ASSERT(dep->namelen != 0);
507
508 if (xfs_sb_version_hasftype(&mp->m_sb))
509 dep->name[dep->namelen] = type;
510}
511
512/*
513 * Pointer to an entry's tag word.
514 */
515static inline __be16 *
516xfs_dir3_data_entry_tag_p(
517 struct xfs_mount *mp,
518 struct xfs_dir2_data_entry *dep)
519{
520 return (__be16 *)((char *)dep +
521 xfs_dir3_data_entsize(mp, dep->namelen) - sizeof(__be16));
522}
523
524/*
525 * Pointer to a freespace's tag word. 459 * Pointer to a freespace's tag word.
526 */ 460 */
527static inline __be16 * 461static inline __be16 *
@@ -562,63 +496,6 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
562} 496}
563 497
564/* 498/*
565 * Offsets of . and .. in data space (always block 0)
566 *
567 * XXX: there is scope for significant optimisation of the logic here. Right
568 * now we are checking for "dir3 format" over and over again. Ideally we should
569 * only do it once for each operation.
570 */
571static inline xfs_dir2_data_aoff_t
572xfs_dir3_data_dot_offset(struct xfs_mount *mp)
573{
574 return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb));
575}
576
577static inline xfs_dir2_data_aoff_t
578xfs_dir3_data_dotdot_offset(struct xfs_mount *mp)
579{
580 return xfs_dir3_data_dot_offset(mp) +
581 xfs_dir3_data_entsize(mp, 1);
582}
583
584static inline xfs_dir2_data_aoff_t
585xfs_dir3_data_first_offset(struct xfs_mount *mp)
586{
587 return xfs_dir3_data_dotdot_offset(mp) +
588 xfs_dir3_data_entsize(mp, 2);
589}
590
591/*
592 * location of . and .. in data space (always block 0)
593 */
594static inline struct xfs_dir2_data_entry *
595xfs_dir3_data_dot_entry_p(
596 struct xfs_mount *mp,
597 struct xfs_dir2_data_hdr *hdr)
598{
599 return (struct xfs_dir2_data_entry *)
600 ((char *)hdr + xfs_dir3_data_dot_offset(mp));
601}
602
603static inline struct xfs_dir2_data_entry *
604xfs_dir3_data_dotdot_entry_p(
605 struct xfs_mount *mp,
606 struct xfs_dir2_data_hdr *hdr)
607{
608 return (struct xfs_dir2_data_entry *)
609 ((char *)hdr + xfs_dir3_data_dotdot_offset(mp));
610}
611
612static inline struct xfs_dir2_data_entry *
613xfs_dir3_data_first_entry_p(
614 struct xfs_mount *mp,
615 struct xfs_dir2_data_hdr *hdr)
616{
617 return (struct xfs_dir2_data_entry *)
618 ((char *)hdr + xfs_dir3_data_first_offset(mp));
619}
620
621/*
622 * Leaf block structures. 499 * Leaf block structures.
623 * 500 *
624 * A pure leaf block looks like the following drawing on disk: 501 * A pure leaf block looks like the following drawing on disk:
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h
index 0e94b3e662af..c0a45923cce0 100644
--- a/fs/xfs/xfs_dir2.h
+++ b/fs/xfs/xfs_dir2.h
@@ -50,6 +50,22 @@ struct xfs_dir_ops {
50 xfs_ino_t (*sf_get_parent_ino)(struct xfs_dir2_sf_hdr *hdr); 50 xfs_ino_t (*sf_get_parent_ino)(struct xfs_dir2_sf_hdr *hdr);
51 void (*sf_put_parent_ino)(struct xfs_dir2_sf_hdr *hdr, 51 void (*sf_put_parent_ino)(struct xfs_dir2_sf_hdr *hdr,
52 xfs_ino_t ino); 52 xfs_ino_t ino);
53
54 int (*data_entsize)(int len);
55 __uint8_t (*data_get_ftype)(struct xfs_dir2_data_entry *dep);
56 void (*data_put_ftype)(struct xfs_dir2_data_entry *dep,
57 __uint8_t ftype);
58 __be16 * (*data_entry_tag_p)(struct xfs_dir2_data_entry *dep);
59
60 xfs_dir2_data_aoff_t (*data_dot_offset)(void);
61 xfs_dir2_data_aoff_t (*data_dotdot_offset)(void);
62 xfs_dir2_data_aoff_t (*data_first_offset)(void);
63 struct xfs_dir2_data_entry *
64 (*data_dot_entry_p)(struct xfs_dir2_data_hdr *hdr);
65 struct xfs_dir2_data_entry *
66 (*data_dotdot_entry_p)(struct xfs_dir2_data_hdr *hdr);
67 struct xfs_dir2_data_entry *
68 (*data_first_entry_p)(struct xfs_dir2_data_hdr *hdr);
53}; 69};
54 70
55extern const struct xfs_dir_ops xfs_dir2_ops; 71extern const struct xfs_dir_ops xfs_dir2_ops;
@@ -95,10 +111,10 @@ extern int xfs_dir2_isleaf(struct xfs_trans *tp, struct xfs_inode *dp, int *r);
95extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, 111extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
96 struct xfs_buf *bp); 112 struct xfs_buf *bp);
97 113
98extern void xfs_dir2_data_freescan(struct xfs_mount *mp, 114extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
99 struct xfs_dir2_data_hdr *hdr, int *loghead); 115 struct xfs_dir2_data_hdr *hdr, int *loghead);
100extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_buf *bp, 116extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_inode *dp,
101 struct xfs_dir2_data_entry *dep); 117 struct xfs_buf *bp, struct xfs_dir2_data_entry *dep);
102extern void xfs_dir2_data_log_header(struct xfs_trans *tp, 118extern void xfs_dir2_data_log_header(struct xfs_trans *tp,
103 struct xfs_buf *bp); 119 struct xfs_buf *bp);
104extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_buf *bp, 120extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_buf *bp,
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 960f3ab526f6..507ef6a7d1f9 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -280,6 +280,7 @@ out:
280static void 280static void
281xfs_dir2_block_compact( 281xfs_dir2_block_compact(
282 struct xfs_trans *tp, 282 struct xfs_trans *tp,
283 struct xfs_inode *dp,
283 struct xfs_buf *bp, 284 struct xfs_buf *bp,
284 struct xfs_dir2_data_hdr *hdr, 285 struct xfs_dir2_data_hdr *hdr,
285 struct xfs_dir2_block_tail *btp, 286 struct xfs_dir2_block_tail *btp,
@@ -323,7 +324,7 @@ xfs_dir2_block_compact(
323 * This needs to happen before the next call to use_free. 324 * This needs to happen before the next call to use_free.
324 */ 325 */
325 if (needscan) 326 if (needscan)
326 xfs_dir2_data_freescan(tp->t_mountp, hdr, needlog); 327 xfs_dir2_data_freescan(dp, hdr, needlog);
327} 328}
328 329
329/* 330/*
@@ -369,7 +370,7 @@ xfs_dir2_block_addname(
369 if (error) 370 if (error)
370 return error; 371 return error;
371 372
372 len = xfs_dir3_data_entsize(mp, args->namelen); 373 len = dp->d_ops->data_entsize(args->namelen);
373 374
374 /* 375 /*
375 * Set up pointers to parts of the block. 376 * Set up pointers to parts of the block.
@@ -418,7 +419,7 @@ xfs_dir2_block_addname(
418 * If need to compact the leaf entries, do it now. 419 * If need to compact the leaf entries, do it now.
419 */ 420 */
420 if (compact) { 421 if (compact) {
421 xfs_dir2_block_compact(tp, bp, hdr, btp, blp, &needlog, 422 xfs_dir2_block_compact(tp, dp, bp, hdr, btp, blp, &needlog,
422 &lfloghigh, &lfloglow); 423 &lfloghigh, &lfloglow);
423 /* recalculate blp post-compaction */ 424 /* recalculate blp post-compaction */
424 blp = xfs_dir2_block_leaf_p(btp); 425 blp = xfs_dir2_block_leaf_p(btp);
@@ -468,7 +469,7 @@ xfs_dir2_block_addname(
468 * This needs to happen before the next call to use_free. 469 * This needs to happen before the next call to use_free.
469 */ 470 */
470 if (needscan) { 471 if (needscan) {
471 xfs_dir2_data_freescan(mp, hdr, &needlog); 472 xfs_dir2_data_freescan(dp, hdr, &needlog);
472 needscan = 0; 473 needscan = 0;
473 } 474 }
474 /* 475 /*
@@ -549,18 +550,18 @@ xfs_dir2_block_addname(
549 dep->inumber = cpu_to_be64(args->inumber); 550 dep->inumber = cpu_to_be64(args->inumber);
550 dep->namelen = args->namelen; 551 dep->namelen = args->namelen;
551 memcpy(dep->name, args->name, args->namelen); 552 memcpy(dep->name, args->name, args->namelen);
552 xfs_dir3_dirent_put_ftype(mp, dep, args->filetype); 553 dp->d_ops->data_put_ftype(dep, args->filetype);
553 tagp = xfs_dir3_data_entry_tag_p(mp, dep); 554 tagp = dp->d_ops->data_entry_tag_p(dep);
554 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 555 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
555 /* 556 /*
556 * Clean up the bestfree array and log the header, tail, and entry. 557 * Clean up the bestfree array and log the header, tail, and entry.
557 */ 558 */
558 if (needscan) 559 if (needscan)
559 xfs_dir2_data_freescan(mp, hdr, &needlog); 560 xfs_dir2_data_freescan(dp, hdr, &needlog);
560 if (needlog) 561 if (needlog)
561 xfs_dir2_data_log_header(tp, bp); 562 xfs_dir2_data_log_header(tp, bp);
562 xfs_dir2_block_log_tail(tp, bp); 563 xfs_dir2_block_log_tail(tp, bp);
563 xfs_dir2_data_log_entry(tp, bp, dep); 564 xfs_dir2_data_log_entry(tp, dp, bp, dep);
564 xfs_dir3_data_check(dp, bp); 565 xfs_dir3_data_check(dp, bp);
565 return 0; 566 return 0;
566} 567}
@@ -642,7 +643,7 @@ xfs_dir2_block_lookup(
642 * Fill in inode number, CI name if appropriate, release the block. 643 * Fill in inode number, CI name if appropriate, release the block.
643 */ 644 */
644 args->inumber = be64_to_cpu(dep->inumber); 645 args->inumber = be64_to_cpu(dep->inumber);
645 args->filetype = xfs_dir3_dirent_get_ftype(mp, dep); 646 args->filetype = dp->d_ops->data_get_ftype(dep);
646 error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); 647 error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
647 xfs_trans_brelse(args->trans, bp); 648 xfs_trans_brelse(args->trans, bp);
648 return XFS_ERROR(error); 649 return XFS_ERROR(error);
@@ -801,7 +802,7 @@ xfs_dir2_block_removename(
801 needlog = needscan = 0; 802 needlog = needscan = 0;
802 xfs_dir2_data_make_free(tp, bp, 803 xfs_dir2_data_make_free(tp, bp,
803 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), 804 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
804 xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan); 805 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
805 /* 806 /*
806 * Fix up the block tail. 807 * Fix up the block tail.
807 */ 808 */
@@ -816,7 +817,7 @@ xfs_dir2_block_removename(
816 * Fix up bestfree, log the header if necessary. 817 * Fix up bestfree, log the header if necessary.
817 */ 818 */
818 if (needscan) 819 if (needscan)
819 xfs_dir2_data_freescan(mp, hdr, &needlog); 820 xfs_dir2_data_freescan(dp, hdr, &needlog);
820 if (needlog) 821 if (needlog)
821 xfs_dir2_data_log_header(tp, bp); 822 xfs_dir2_data_log_header(tp, bp);
822 xfs_dir3_data_check(dp, bp); 823 xfs_dir3_data_check(dp, bp);
@@ -875,8 +876,8 @@ xfs_dir2_block_replace(
875 * Change the inode number to the new value. 876 * Change the inode number to the new value.
876 */ 877 */
877 dep->inumber = cpu_to_be64(args->inumber); 878 dep->inumber = cpu_to_be64(args->inumber);
878 xfs_dir3_dirent_put_ftype(mp, dep, args->filetype); 879 dp->d_ops->data_put_ftype(dep, args->filetype);
879 xfs_dir2_data_log_entry(args->trans, bp, dep); 880 xfs_dir2_data_log_entry(args->trans, dp, bp, dep);
880 xfs_dir3_data_check(dp, bp); 881 xfs_dir3_data_check(dp, bp);
881 return 0; 882 return 0;
882} 883}
@@ -1023,7 +1024,7 @@ xfs_dir2_leaf_to_block(
1023 * Scan the bestfree if we need it and log the data block header. 1024 * Scan the bestfree if we need it and log the data block header.
1024 */ 1025 */
1025 if (needscan) 1026 if (needscan)
1026 xfs_dir2_data_freescan(mp, hdr, &needlog); 1027 xfs_dir2_data_freescan(dp, hdr, &needlog);
1027 if (needlog) 1028 if (needlog)
1028 xfs_dir2_data_log_header(tp, dbp); 1029 xfs_dir2_data_log_header(tp, dbp);
1029 /* 1030 /*
@@ -1158,32 +1159,32 @@ xfs_dir2_sf_to_block(
1158 /* 1159 /*
1159 * Create entry for . 1160 * Create entry for .
1160 */ 1161 */
1161 dep = xfs_dir3_data_dot_entry_p(mp, hdr); 1162 dep = dp->d_ops->data_dot_entry_p(hdr);
1162 dep->inumber = cpu_to_be64(dp->i_ino); 1163 dep->inumber = cpu_to_be64(dp->i_ino);
1163 dep->namelen = 1; 1164 dep->namelen = 1;
1164 dep->name[0] = '.'; 1165 dep->name[0] = '.';
1165 xfs_dir3_dirent_put_ftype(mp, dep, XFS_DIR3_FT_DIR); 1166 dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
1166 tagp = xfs_dir3_data_entry_tag_p(mp, dep); 1167 tagp = dp->d_ops->data_entry_tag_p(dep);
1167 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1168 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1168 xfs_dir2_data_log_entry(tp, bp, dep); 1169 xfs_dir2_data_log_entry(tp, dp, bp, dep);
1169 blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); 1170 blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
1170 blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1171 blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
1171 (char *)dep - (char *)hdr)); 1172 (char *)dep - (char *)hdr));
1172 /* 1173 /*
1173 * Create entry for .. 1174 * Create entry for ..
1174 */ 1175 */
1175 dep = xfs_dir3_data_dotdot_entry_p(mp, hdr); 1176 dep = dp->d_ops->data_dotdot_entry_p(hdr);
1176 dep->inumber = cpu_to_be64(dp->d_ops->sf_get_parent_ino(sfp)); 1177 dep->inumber = cpu_to_be64(dp->d_ops->sf_get_parent_ino(sfp));
1177 dep->namelen = 2; 1178 dep->namelen = 2;
1178 dep->name[0] = dep->name[1] = '.'; 1179 dep->name[0] = dep->name[1] = '.';
1179 xfs_dir3_dirent_put_ftype(mp, dep, XFS_DIR3_FT_DIR); 1180 dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
1180 tagp = xfs_dir3_data_entry_tag_p(mp, dep); 1181 tagp = dp->d_ops->data_entry_tag_p(dep);
1181 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1182 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1182 xfs_dir2_data_log_entry(tp, bp, dep); 1183 xfs_dir2_data_log_entry(tp, dp, bp, dep);
1183 blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); 1184 blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
1184 blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, 1185 blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
1185 (char *)dep - (char *)hdr)); 1186 (char *)dep - (char *)hdr));
1186 offset = xfs_dir3_data_first_offset(mp); 1187 offset = dp->d_ops->data_first_offset();
1187 /* 1188 /*
1188 * Loop over existing entries, stuff them in. 1189 * Loop over existing entries, stuff them in.
1189 */ 1190 */
@@ -1224,12 +1225,11 @@ xfs_dir2_sf_to_block(
1224 dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset); 1225 dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset);
1225 dep->inumber = cpu_to_be64(dp->d_ops->sf_get_ino(sfp, sfep)); 1226 dep->inumber = cpu_to_be64(dp->d_ops->sf_get_ino(sfp, sfep));
1226 dep->namelen = sfep->namelen; 1227 dep->namelen = sfep->namelen;
1227 xfs_dir3_dirent_put_ftype(mp, dep, 1228 dp->d_ops->data_put_ftype(dep, dp->d_ops->sf_get_ftype(sfep));
1228 dp->d_ops->sf_get_ftype(sfep));
1229 memcpy(dep->name, sfep->name, dep->namelen); 1229 memcpy(dep->name, sfep->name, dep->namelen);
1230 tagp = xfs_dir3_data_entry_tag_p(mp, dep); 1230 tagp = dp->d_ops->data_entry_tag_p(dep);
1231 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 1231 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
1232 xfs_dir2_data_log_entry(tp, bp, dep); 1232 xfs_dir2_data_log_entry(tp, dp, bp, dep);
1233 name.name = sfep->name; 1233 name.name = sfep->name;
1234 name.len = sfep->namelen; 1234 name.len = sfep->namelen;
1235 blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> 1235 blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index ccfeb4d8376a..00006b3db054 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -62,12 +62,26 @@ __xfs_dir3_data_check(
62 char *p; /* current data position */ 62 char *p; /* current data position */
63 int stale; /* count of stale leaves */ 63 int stale; /* count of stale leaves */
64 struct xfs_name name; 64 struct xfs_name name;
65 const struct xfs_dir_ops *ops;
65 66
66 mp = bp->b_target->bt_mount; 67 mp = bp->b_target->bt_mount;
67 hdr = bp->b_addr; 68 hdr = bp->b_addr;
68 bf = xfs_dir3_data_bestfree_p(hdr); 69 bf = xfs_dir3_data_bestfree_p(hdr);
69 p = (char *)xfs_dir3_data_entry_p(hdr); 70 p = (char *)xfs_dir3_data_entry_p(hdr);
70 71
72 /*
73 * We can be passed a null dp here from a verifier, so manually
74 * configure the ops here in that case.
75 */
76 if (dp)
77 ops = dp->d_ops;
78 else if (xfs_sb_version_hascrc(&mp->m_sb))
79 ops = &xfs_dir3_ops;
80 else if (xfs_sb_version_hasftype(&mp->m_sb))
81 ops = &xfs_dir2_ftype_ops;
82 else
83 ops = &xfs_dir2_ops;
84
71 switch (hdr->magic) { 85 switch (hdr->magic) {
72 case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): 86 case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
73 case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): 87 case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
@@ -146,10 +160,10 @@ __xfs_dir3_data_check(
146 XFS_WANT_CORRUPTED_RETURN( 160 XFS_WANT_CORRUPTED_RETURN(
147 !xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber))); 161 !xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)));
148 XFS_WANT_CORRUPTED_RETURN( 162 XFS_WANT_CORRUPTED_RETURN(
149 be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep)) == 163 be16_to_cpu(*ops->data_entry_tag_p(dep)) ==
150 (char *)dep - (char *)hdr); 164 (char *)dep - (char *)hdr);
151 XFS_WANT_CORRUPTED_RETURN( 165 XFS_WANT_CORRUPTED_RETURN(
152 xfs_dir3_dirent_get_ftype(mp, dep) < XFS_DIR3_FT_MAX); 166 ops->data_get_ftype(dep) < XFS_DIR3_FT_MAX);
153 count++; 167 count++;
154 lastfree = 0; 168 lastfree = 0;
155 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 169 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
@@ -167,7 +181,7 @@ __xfs_dir3_data_check(
167 } 181 }
168 XFS_WANT_CORRUPTED_RETURN(i < be32_to_cpu(btp->count)); 182 XFS_WANT_CORRUPTED_RETURN(i < be32_to_cpu(btp->count));
169 } 183 }
170 p += xfs_dir3_data_entsize(mp, dep->namelen); 184 p += ops->data_entsize(dep->namelen);
171 } 185 }
172 /* 186 /*
173 * Need to have seen all the entries and all the bestfree slots. 187 * Need to have seen all the entries and all the bestfree slots.
@@ -485,9 +499,9 @@ xfs_dir2_data_freeremove(
485 */ 499 */
486void 500void
487xfs_dir2_data_freescan( 501xfs_dir2_data_freescan(
488 xfs_mount_t *mp, /* filesystem mount point */ 502 struct xfs_inode *dp,
489 xfs_dir2_data_hdr_t *hdr, /* data block header */ 503 struct xfs_dir2_data_hdr *hdr,
490 int *loghead) /* out: log data header */ 504 int *loghead)
491{ 505{
492 xfs_dir2_block_tail_t *btp; /* block tail */ 506 xfs_dir2_block_tail_t *btp; /* block tail */
493 xfs_dir2_data_entry_t *dep; /* active data entry */ 507 xfs_dir2_data_entry_t *dep; /* active data entry */
@@ -513,10 +527,10 @@ xfs_dir2_data_freescan(
513 p = (char *)xfs_dir3_data_entry_p(hdr); 527 p = (char *)xfs_dir3_data_entry_p(hdr);
514 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 528 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
515 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { 529 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
516 btp = xfs_dir2_block_tail_p(mp, hdr); 530 btp = xfs_dir2_block_tail_p(dp->i_mount, hdr);
517 endp = (char *)xfs_dir2_block_leaf_p(btp); 531 endp = (char *)xfs_dir2_block_leaf_p(btp);
518 } else 532 } else
519 endp = (char *)hdr + mp->m_dirblksize; 533 endp = (char *)hdr + dp->i_mount->m_dirblksize;
520 /* 534 /*
521 * Loop over the block's entries. 535 * Loop over the block's entries.
522 */ 536 */
@@ -537,8 +551,8 @@ xfs_dir2_data_freescan(
537 else { 551 else {
538 dep = (xfs_dir2_data_entry_t *)p; 552 dep = (xfs_dir2_data_entry_t *)p;
539 ASSERT((char *)dep - (char *)hdr == 553 ASSERT((char *)dep - (char *)hdr ==
540 be16_to_cpu(*xfs_dir3_data_entry_tag_p(mp, dep))); 554 be16_to_cpu(*dp->d_ops->data_entry_tag_p(dep)));
541 p += xfs_dir3_data_entsize(mp, dep->namelen); 555 p += dp->d_ops->data_entsize(dep->namelen);
542 } 556 }
543 } 557 }
544} 558}
@@ -625,11 +639,11 @@ xfs_dir3_data_init(
625void 639void
626xfs_dir2_data_log_entry( 640xfs_dir2_data_log_entry(
627 struct xfs_trans *tp, 641 struct xfs_trans *tp,
642 struct xfs_inode *dp,
628 struct xfs_buf *bp, 643 struct xfs_buf *bp,
629 xfs_dir2_data_entry_t *dep) /* data entry pointer */ 644 xfs_dir2_data_entry_t *dep) /* data entry pointer */
630{ 645{
631 struct xfs_dir2_data_hdr *hdr = bp->b_addr; 646 struct xfs_dir2_data_hdr *hdr = bp->b_addr;
632 struct xfs_mount *mp = tp->t_mountp;
633 647
634 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 648 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
635 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || 649 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
@@ -637,7 +651,7 @@ xfs_dir2_data_log_entry(
637 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 651 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
638 652
639 xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr), 653 xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr),
640 (uint)((char *)(xfs_dir3_data_entry_tag_p(mp, dep) + 1) - 654 (uint)((char *)(dp->d_ops->data_entry_tag_p(dep) + 1) -
641 (char *)hdr - 1)); 655 (char *)hdr - 1));
642} 656}
643 657
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 51fdc11a1e2c..dd195363ccf2 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -500,7 +500,7 @@ xfs_dir2_block_to_leaf(
500 hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); 500 hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
501 501
502 if (needscan) 502 if (needscan)
503 xfs_dir2_data_freescan(mp, hdr, &needlog); 503 xfs_dir2_data_freescan(dp, hdr, &needlog);
504 /* 504 /*
505 * Set up leaf tail and bests table. 505 * Set up leaf tail and bests table.
506 */ 506 */
@@ -700,7 +700,7 @@ xfs_dir2_leaf_addname(
700 ents = xfs_dir3_leaf_ents_p(leaf); 700 ents = xfs_dir3_leaf_ents_p(leaf);
701 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); 701 xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
702 bestsp = xfs_dir2_leaf_bests_p(ltp); 702 bestsp = xfs_dir2_leaf_bests_p(ltp);
703 length = xfs_dir3_data_entsize(mp, args->namelen); 703 length = dp->d_ops->data_entsize(args->namelen);
704 704
705 /* 705 /*
706 * See if there are any entries with the same hash value 706 * See if there are any entries with the same hash value
@@ -901,20 +901,20 @@ xfs_dir2_leaf_addname(
901 dep->inumber = cpu_to_be64(args->inumber); 901 dep->inumber = cpu_to_be64(args->inumber);
902 dep->namelen = args->namelen; 902 dep->namelen = args->namelen;
903 memcpy(dep->name, args->name, dep->namelen); 903 memcpy(dep->name, args->name, dep->namelen);
904 xfs_dir3_dirent_put_ftype(mp, dep, args->filetype); 904 dp->d_ops->data_put_ftype(dep, args->filetype);
905 tagp = xfs_dir3_data_entry_tag_p(mp, dep); 905 tagp = dp->d_ops->data_entry_tag_p(dep);
906 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 906 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
907 /* 907 /*
908 * Need to scan fix up the bestfree table. 908 * Need to scan fix up the bestfree table.
909 */ 909 */
910 if (needscan) 910 if (needscan)
911 xfs_dir2_data_freescan(mp, hdr, &needlog); 911 xfs_dir2_data_freescan(dp, hdr, &needlog);
912 /* 912 /*
913 * Need to log the data block's header. 913 * Need to log the data block's header.
914 */ 914 */
915 if (needlog) 915 if (needlog)
916 xfs_dir2_data_log_header(tp, dbp); 916 xfs_dir2_data_log_header(tp, dbp);
917 xfs_dir2_data_log_entry(tp, dbp, dep); 917 xfs_dir2_data_log_entry(tp, dp, dbp, dep);
918 /* 918 /*
919 * If the bests table needs to be changed, do it. 919 * If the bests table needs to be changed, do it.
920 * Log the change unless we've already done that. 920 * Log the change unless we've already done that.
@@ -1230,7 +1230,7 @@ xfs_dir2_leaf_lookup(
1230 * Return the found inode number & CI name if appropriate 1230 * Return the found inode number & CI name if appropriate
1231 */ 1231 */
1232 args->inumber = be64_to_cpu(dep->inumber); 1232 args->inumber = be64_to_cpu(dep->inumber);
1233 args->filetype = xfs_dir3_dirent_get_ftype(dp->i_mount, dep); 1233 args->filetype = dp->d_ops->data_get_ftype(dep);
1234 error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); 1234 error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
1235 xfs_trans_brelse(tp, dbp); 1235 xfs_trans_brelse(tp, dbp);
1236 xfs_trans_brelse(tp, lbp); 1236 xfs_trans_brelse(tp, lbp);
@@ -1433,7 +1433,7 @@ xfs_dir2_leaf_removename(
1433 */ 1433 */
1434 xfs_dir2_data_make_free(tp, dbp, 1434 xfs_dir2_data_make_free(tp, dbp,
1435 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), 1435 (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
1436 xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan); 1436 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
1437 /* 1437 /*
1438 * We just mark the leaf entry stale by putting a null in it. 1438 * We just mark the leaf entry stale by putting a null in it.
1439 */ 1439 */
@@ -1449,7 +1449,7 @@ xfs_dir2_leaf_removename(
1449 * log the data block header if necessary. 1449 * log the data block header if necessary.
1450 */ 1450 */
1451 if (needscan) 1451 if (needscan)
1452 xfs_dir2_data_freescan(mp, hdr, &needlog); 1452 xfs_dir2_data_freescan(dp, hdr, &needlog);
1453 if (needlog) 1453 if (needlog)
1454 xfs_dir2_data_log_header(tp, dbp); 1454 xfs_dir2_data_log_header(tp, dbp);
1455 /* 1455 /*
@@ -1561,9 +1561,9 @@ xfs_dir2_leaf_replace(
1561 * Put the new inode number in, log it. 1561 * Put the new inode number in, log it.
1562 */ 1562 */
1563 dep->inumber = cpu_to_be64(args->inumber); 1563 dep->inumber = cpu_to_be64(args->inumber);
1564 xfs_dir3_dirent_put_ftype(dp->i_mount, dep, args->filetype); 1564 dp->d_ops->data_put_ftype(dep, args->filetype);
1565 tp = args->trans; 1565 tp = args->trans;
1566 xfs_dir2_data_log_entry(tp, dbp, dep); 1566 xfs_dir2_data_log_entry(tp, dp, dbp, dep);
1567 xfs_dir3_leaf_check(dp->i_mount, lbp); 1567 xfs_dir3_leaf_check(dp->i_mount, lbp);
1568 xfs_trans_brelse(tp, lbp); 1568 xfs_trans_brelse(tp, lbp);
1569 return 0; 1569 return 0;
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index b8381646b8af..a1d133981c14 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -604,7 +604,7 @@ xfs_dir2_leafn_lookup_for_addname(
604 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || 604 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
605 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); 605 free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
606 } 606 }
607 length = xfs_dir3_data_entsize(mp, args->namelen); 607 length = dp->d_ops->data_entsize(args->namelen);
608 /* 608 /*
609 * Loop over leaf entries with the right hash value. 609 * Loop over leaf entries with the right hash value.
610 */ 610 */
@@ -815,7 +815,7 @@ xfs_dir2_leafn_lookup_for_entry(
815 xfs_trans_brelse(tp, state->extrablk.bp); 815 xfs_trans_brelse(tp, state->extrablk.bp);
816 args->cmpresult = cmp; 816 args->cmpresult = cmp;
817 args->inumber = be64_to_cpu(dep->inumber); 817 args->inumber = be64_to_cpu(dep->inumber);
818 args->filetype = xfs_dir3_dirent_get_ftype(mp, dep); 818 args->filetype = dp->d_ops->data_get_ftype(dep);
819 *indexp = index; 819 *indexp = index;
820 state->extravalid = 1; 820 state->extravalid = 1;
821 state->extrablk.bp = curbp; 821 state->extrablk.bp = curbp;
@@ -1259,13 +1259,13 @@ xfs_dir2_leafn_remove(
1259 longest = be16_to_cpu(bf[0].length); 1259 longest = be16_to_cpu(bf[0].length);
1260 needlog = needscan = 0; 1260 needlog = needscan = 0;
1261 xfs_dir2_data_make_free(tp, dbp, off, 1261 xfs_dir2_data_make_free(tp, dbp, off,
1262 xfs_dir3_data_entsize(mp, dep->namelen), &needlog, &needscan); 1262 dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
1263 /* 1263 /*
1264 * Rescan the data block freespaces for bestfree. 1264 * Rescan the data block freespaces for bestfree.
1265 * Log the data block header if needed. 1265 * Log the data block header if needed.
1266 */ 1266 */
1267 if (needscan) 1267 if (needscan)
1268 xfs_dir2_data_freescan(mp, hdr, &needlog); 1268 xfs_dir2_data_freescan(dp, hdr, &needlog);
1269 if (needlog) 1269 if (needlog)
1270 xfs_dir2_data_log_header(tp, dbp); 1270 xfs_dir2_data_log_header(tp, dbp);
1271 xfs_dir3_data_check(dp, dbp); 1271 xfs_dir3_data_check(dp, dbp);
@@ -1711,7 +1711,7 @@ xfs_dir2_node_addname_int(
1711 dp = args->dp; 1711 dp = args->dp;
1712 mp = dp->i_mount; 1712 mp = dp->i_mount;
1713 tp = args->trans; 1713 tp = args->trans;
1714 length = xfs_dir3_data_entsize(mp, args->namelen); 1714 length = dp->d_ops->data_entsize(args->namelen);
1715 /* 1715 /*
1716 * If we came in with a freespace block that means that lookup 1716 * If we came in with a freespace block that means that lookup
1717 * found an entry with our hash value. This is the freespace 1717 * found an entry with our hash value. This is the freespace
@@ -2007,15 +2007,15 @@ xfs_dir2_node_addname_int(
2007 dep->inumber = cpu_to_be64(args->inumber); 2007 dep->inumber = cpu_to_be64(args->inumber);
2008 dep->namelen = args->namelen; 2008 dep->namelen = args->namelen;
2009 memcpy(dep->name, args->name, dep->namelen); 2009 memcpy(dep->name, args->name, dep->namelen);
2010 xfs_dir3_dirent_put_ftype(mp, dep, args->filetype); 2010 dp->d_ops->data_put_ftype(dep, args->filetype);
2011 tagp = xfs_dir3_data_entry_tag_p(mp, dep); 2011 tagp = dp->d_ops->data_entry_tag_p(dep);
2012 *tagp = cpu_to_be16((char *)dep - (char *)hdr); 2012 *tagp = cpu_to_be16((char *)dep - (char *)hdr);
2013 xfs_dir2_data_log_entry(tp, dbp, dep); 2013 xfs_dir2_data_log_entry(tp, dp, dbp, dep);
2014 /* 2014 /*
2015 * Rescan the block for bestfree if needed. 2015 * Rescan the block for bestfree if needed.
2016 */ 2016 */
2017 if (needscan) 2017 if (needscan)
2018 xfs_dir2_data_freescan(mp, hdr, &needlog); 2018 xfs_dir2_data_freescan(dp, hdr, &needlog);
2019 /* 2019 /*
2020 * Log the data block header if needed. 2020 * Log the data block header if needed.
2021 */ 2021 */
@@ -2228,8 +2228,9 @@ xfs_dir2_node_replace(
2228 * Fill in the new inode number and log the entry. 2228 * Fill in the new inode number and log the entry.
2229 */ 2229 */
2230 dep->inumber = cpu_to_be64(inum); 2230 dep->inumber = cpu_to_be64(inum);
2231 xfs_dir3_dirent_put_ftype(state->mp, dep, args->filetype); 2231 args->dp->d_ops->data_put_ftype(dep, args->filetype);
2232 xfs_dir2_data_log_entry(args->trans, state->extrablk.bp, dep); 2232 xfs_dir2_data_log_entry(args->trans, args->dp,
2233 state->extrablk.bp, dep);
2233 rval = 0; 2234 rval = 0;
2234 } 2235 }
2235 /* 2236 /*
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index 2d2c8fb05541..b99aa7d48e90 100644
--- a/fs/xfs/xfs_dir2_readdir.c
+++ b/fs/xfs/xfs_dir2_readdir.c
@@ -119,9 +119,9 @@ xfs_dir2_sf_getdents(
119 * mp->m_dirdatablk. 119 * mp->m_dirdatablk.
120 */ 120 */
121 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 121 dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
122 xfs_dir3_data_dot_offset(mp)); 122 dp->d_ops->data_dot_offset());
123 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, 123 dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
124 xfs_dir3_data_dotdot_offset(mp)); 124 dp->d_ops->data_dotdot_offset());
125 125
126 /* 126 /*
127 * Put . entry unless we're starting past it. 127 * Put . entry unless we're starting past it.
@@ -237,7 +237,7 @@ xfs_dir2_block_getdents(
237 /* 237 /*
238 * Bump pointer for the next iteration. 238 * Bump pointer for the next iteration.
239 */ 239 */
240 ptr += xfs_dir3_data_entsize(mp, dep->namelen); 240 ptr += dp->d_ops->data_entsize(dep->namelen);
241 /* 241 /*
242 * The entry is before the desired starting point, skip it. 242 * The entry is before the desired starting point, skip it.
243 */ 243 */
@@ -248,7 +248,7 @@ xfs_dir2_block_getdents(
248 (char *)dep - (char *)hdr); 248 (char *)dep - (char *)hdr);
249 249
250 ctx->pos = cook & 0x7fffffff; 250 ctx->pos = cook & 0x7fffffff;
251 filetype = xfs_dir3_dirent_get_ftype(mp, dep); 251 filetype = dp->d_ops->data_get_ftype(dep);
252 /* 252 /*
253 * If it didn't fit, set the final offset to here & return. 253 * If it didn't fit, set the final offset to here & return.
254 */ 254 */
@@ -601,7 +601,7 @@ xfs_dir2_leaf_getdents(
601 } 601 }
602 dep = (xfs_dir2_data_entry_t *)ptr; 602 dep = (xfs_dir2_data_entry_t *)ptr;
603 length = 603 length =
604 xfs_dir3_data_entsize(mp, dep->namelen); 604 dp->d_ops->data_entsize(dep->namelen);
605 ptr += length; 605 ptr += length;
606 } 606 }
607 /* 607 /*
@@ -632,8 +632,8 @@ xfs_dir2_leaf_getdents(
632 } 632 }
633 633
634 dep = (xfs_dir2_data_entry_t *)ptr; 634 dep = (xfs_dir2_data_entry_t *)ptr;
635 length = xfs_dir3_data_entsize(mp, dep->namelen); 635 length = dp->d_ops->data_entsize(dep->namelen);
636 filetype = xfs_dir3_dirent_get_ftype(mp, dep); 636 filetype = dp->d_ops->data_get_ftype(dep);
637 637
638 ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff; 638 ctx->pos = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff;
639 if (!dir_emit(ctx, (char *)dep->name, dep->namelen, 639 if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index ec0d39b5fa12..953e19479151 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -251,11 +251,11 @@ xfs_dir2_block_to_sf(
251 dp->d_ops->sf_put_ino(sfp, sfep, 251 dp->d_ops->sf_put_ino(sfp, sfep,
252 be64_to_cpu(dep->inumber)); 252 be64_to_cpu(dep->inumber));
253 dp->d_ops->sf_put_ftype(sfep, 253 dp->d_ops->sf_put_ftype(sfep,
254 xfs_dir3_dirent_get_ftype(mp, dep)); 254 dp->d_ops->data_get_ftype(dep));
255 255
256 sfep = dp->d_ops->sf_nextentry(sfp, sfep); 256 sfep = dp->d_ops->sf_nextentry(sfp, sfep);
257 } 257 }
258 ptr += xfs_dir3_data_entsize(mp, dep->namelen); 258 ptr += dp->d_ops->data_entsize(dep->namelen);
259 } 259 }
260 ASSERT((char *)sfep - (char *)sfp == size); 260 ASSERT((char *)sfep - (char *)sfp == size);
261 xfs_dir2_sf_check(args); 261 xfs_dir2_sf_check(args);
@@ -473,12 +473,12 @@ xfs_dir2_sf_addname_hard(
473 * to insert the new entry. 473 * to insert the new entry.
474 * If it's going to end up at the end then oldsfep will point there. 474 * If it's going to end up at the end then oldsfep will point there.
475 */ 475 */
476 for (offset = xfs_dir3_data_first_offset(mp), 476 for (offset = dp->d_ops->data_first_offset(),
477 oldsfep = xfs_dir2_sf_firstentry(oldsfp), 477 oldsfep = xfs_dir2_sf_firstentry(oldsfp),
478 add_datasize = xfs_dir3_data_entsize(mp, args->namelen), 478 add_datasize = dp->d_ops->data_entsize(args->namelen),
479 eof = (char *)oldsfep == &buf[old_isize]; 479 eof = (char *)oldsfep == &buf[old_isize];
480 !eof; 480 !eof;
481 offset = new_offset + xfs_dir3_data_entsize(mp, oldsfep->namelen), 481 offset = new_offset + dp->d_ops->data_entsize(oldsfep->namelen),
482 oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep), 482 oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep),
483 eof = (char *)oldsfep == &buf[old_isize]) { 483 eof = (char *)oldsfep == &buf[old_isize]) {
484 new_offset = xfs_dir2_sf_get_offset(oldsfep); 484 new_offset = xfs_dir2_sf_get_offset(oldsfep);
@@ -555,8 +555,8 @@ xfs_dir2_sf_addname_pick(
555 mp = dp->i_mount; 555 mp = dp->i_mount;
556 556
557 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; 557 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
558 size = xfs_dir3_data_entsize(mp, args->namelen); 558 size = dp->d_ops->data_entsize(args->namelen);
559 offset = xfs_dir3_data_first_offset(mp); 559 offset = dp->d_ops->data_first_offset();
560 sfep = xfs_dir2_sf_firstentry(sfp); 560 sfep = xfs_dir2_sf_firstentry(sfp);
561 holefit = 0; 561 holefit = 0;
562 /* 562 /*
@@ -568,7 +568,7 @@ xfs_dir2_sf_addname_pick(
568 if (!holefit) 568 if (!holefit)
569 holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); 569 holefit = offset + size <= xfs_dir2_sf_get_offset(sfep);
570 offset = xfs_dir2_sf_get_offset(sfep) + 570 offset = xfs_dir2_sf_get_offset(sfep) +
571 xfs_dir3_data_entsize(mp, sfep->namelen); 571 dp->d_ops->data_entsize(sfep->namelen);
572 sfep = dp->d_ops->sf_nextentry(sfp, sfep); 572 sfep = dp->d_ops->sf_nextentry(sfp, sfep);
573 } 573 }
574 /* 574 /*
@@ -629,7 +629,7 @@ xfs_dir2_sf_check(
629 mp = dp->i_mount; 629 mp = dp->i_mount;
630 630
631 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; 631 sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
632 offset = xfs_dir3_data_first_offset(mp); 632 offset = dp->d_ops->data_first_offset();
633 ino = dp->d_ops->sf_get_parent_ino(sfp); 633 ino = dp->d_ops->sf_get_parent_ino(sfp);
634 i8count = ino > XFS_DIR2_MAX_SHORT_INUM; 634 i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
635 635
@@ -641,7 +641,7 @@ xfs_dir2_sf_check(
641 i8count += ino > XFS_DIR2_MAX_SHORT_INUM; 641 i8count += ino > XFS_DIR2_MAX_SHORT_INUM;
642 offset = 642 offset =
643 xfs_dir2_sf_get_offset(sfep) + 643 xfs_dir2_sf_get_offset(sfep) +
644 xfs_dir3_data_entsize(mp, sfep->namelen); 644 dp->d_ops->data_entsize(sfep->namelen);
645 ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); 645 ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX);
646 } 646 }
647 ASSERT(i8count == sfp->i8count); 647 ASSERT(i8count == sfp->i8count);