diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/Makefile | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_da_btree.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_da_format.c | 85 | ||||
-rw-r--r-- | fs/xfs/xfs_da_format.h | 26 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2.c | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2.h | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_block.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_readdir.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_sf.c | 31 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 2 |
12 files changed, 132 insertions, 45 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 33a69fabfd83..c21f43506661 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile | |||
@@ -66,6 +66,7 @@ xfs-y += xfs_alloc.o \ | |||
66 | xfs_bmap_btree.o \ | 66 | xfs_bmap_btree.o \ |
67 | xfs_btree.o \ | 67 | xfs_btree.o \ |
68 | xfs_da_btree.o \ | 68 | xfs_da_btree.o \ |
69 | xfs_da_format.o \ | ||
69 | xfs_dir2.o \ | 70 | xfs_dir2.o \ |
70 | xfs_dir2_block.o \ | 71 | xfs_dir2_block.o \ |
71 | xfs_dir2_data.o \ | 72 | xfs_dir2_data.o \ |
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index e492dcadd032..6e95ea79f5d7 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h | |||
@@ -23,6 +23,7 @@ struct xfs_bmap_free; | |||
23 | struct xfs_inode; | 23 | struct xfs_inode; |
24 | struct xfs_trans; | 24 | struct xfs_trans; |
25 | struct zone; | 25 | struct zone; |
26 | struct xfs_dir_ops; | ||
26 | 27 | ||
27 | /*======================================================================== | 28 | /*======================================================================== |
28 | * Btree searching and modification structure definitions. | 29 | * Btree searching and modification structure definitions. |
diff --git a/fs/xfs/xfs_da_format.c b/fs/xfs/xfs_da_format.c new file mode 100644 index 000000000000..982d105d012f --- /dev/null +++ b/fs/xfs/xfs_da_format.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc. | ||
3 | * Copyright (c) 2013 Red Hat, Inc. | ||
4 | * All Rights Reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it would be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write the Free Software Foundation, | ||
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | */ | ||
19 | #include "xfs.h" | ||
20 | #include "xfs_fs.h" | ||
21 | #include "xfs_format.h" | ||
22 | #include "xfs_log_format.h" | ||
23 | #include "xfs_trans_resv.h" | ||
24 | #include "xfs_sb.h" | ||
25 | #include "xfs_ag.h" | ||
26 | #include "xfs_mount.h" | ||
27 | #include "xfs_da_format.h" | ||
28 | #include "xfs_inode.h" | ||
29 | #include "xfs_dir2.h" | ||
30 | |||
31 | |||
32 | static int | ||
33 | xfs_dir2_sf_entsize( | ||
34 | struct xfs_dir2_sf_hdr *hdr, | ||
35 | int len) | ||
36 | { | ||
37 | int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ | ||
38 | |||
39 | count += len; /* name */ | ||
40 | count += hdr->i8count ? sizeof(xfs_dir2_ino8_t) : | ||
41 | sizeof(xfs_dir2_ino4_t); /* ino # */ | ||
42 | return count; | ||
43 | } | ||
44 | |||
45 | static int | ||
46 | xfs_dir3_sf_entsize( | ||
47 | struct xfs_dir2_sf_hdr *hdr, | ||
48 | int len) | ||
49 | { | ||
50 | return xfs_dir2_sf_entsize(hdr, len) + sizeof(__uint8_t); | ||
51 | } | ||
52 | |||
53 | static struct xfs_dir2_sf_entry * | ||
54 | xfs_dir2_sf_nextentry( | ||
55 | struct xfs_dir2_sf_hdr *hdr, | ||
56 | struct xfs_dir2_sf_entry *sfep) | ||
57 | { | ||
58 | return (struct xfs_dir2_sf_entry *) | ||
59 | ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen)); | ||
60 | } | ||
61 | |||
62 | static struct xfs_dir2_sf_entry * | ||
63 | xfs_dir3_sf_nextentry( | ||
64 | struct xfs_dir2_sf_hdr *hdr, | ||
65 | struct xfs_dir2_sf_entry *sfep) | ||
66 | { | ||
67 | return (struct xfs_dir2_sf_entry *) | ||
68 | ((char *)sfep + xfs_dir3_sf_entsize(hdr, sfep->namelen)); | ||
69 | } | ||
70 | |||
71 | |||
72 | const struct xfs_dir_ops xfs_dir2_ops = { | ||
73 | .sf_entsize = xfs_dir2_sf_entsize, | ||
74 | .sf_nextentry = xfs_dir2_sf_nextentry, | ||
75 | }; | ||
76 | |||
77 | const struct xfs_dir_ops xfs_dir2_ftype_ops = { | ||
78 | .sf_entsize = xfs_dir3_sf_entsize, | ||
79 | .sf_nextentry = xfs_dir3_sf_nextentry, | ||
80 | }; | ||
81 | |||
82 | const struct xfs_dir_ops xfs_dir3_ops = { | ||
83 | .sf_entsize = xfs_dir3_sf_entsize, | ||
84 | .sf_nextentry = xfs_dir3_sf_nextentry, | ||
85 | }; | ||
diff --git a/fs/xfs/xfs_da_format.h b/fs/xfs/xfs_da_format.h index 89a1a219c8ff..d54726d0fc10 100644 --- a/fs/xfs/xfs_da_format.h +++ b/fs/xfs/xfs_da_format.h | |||
@@ -329,32 +329,6 @@ xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr) | |||
329 | ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count)); | 329 | ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count)); |
330 | } | 330 | } |
331 | 331 | ||
332 | static inline int | ||
333 | xfs_dir3_sf_entsize( | ||
334 | struct xfs_mount *mp, | ||
335 | struct xfs_dir2_sf_hdr *hdr, | ||
336 | int len) | ||
337 | { | ||
338 | int count = sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ | ||
339 | |||
340 | count += len; /* name */ | ||
341 | count += hdr->i8count ? sizeof(xfs_dir2_ino8_t) : | ||
342 | sizeof(xfs_dir2_ino4_t); /* ino # */ | ||
343 | if (xfs_sb_version_hasftype(&mp->m_sb)) | ||
344 | count += sizeof(__uint8_t); /* file type */ | ||
345 | return count; | ||
346 | } | ||
347 | |||
348 | static inline struct xfs_dir2_sf_entry * | ||
349 | xfs_dir3_sf_nextentry( | ||
350 | struct xfs_mount *mp, | ||
351 | struct xfs_dir2_sf_hdr *hdr, | ||
352 | struct xfs_dir2_sf_entry *sfep) | ||
353 | { | ||
354 | return (struct xfs_dir2_sf_entry *) | ||
355 | ((char *)sfep + xfs_dir3_sf_entsize(mp, hdr, sfep->namelen)); | ||
356 | } | ||
357 | |||
358 | /* | 332 | /* |
359 | * in dir3 shortform directories, the file type field is stored at a variable | 333 | * in dir3 shortform directories, the file type field is stored at a variable |
360 | * offset after the inode number. Because it's only a single byte, endian | 334 | * offset after the inode number. Because it's only a single byte, endian |
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 38bf9324302c..7911136453cd 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
@@ -112,6 +112,13 @@ xfs_dir_mount( | |||
112 | mp->m_dirnameops = &xfs_ascii_ci_nameops; | 112 | mp->m_dirnameops = &xfs_ascii_ci_nameops; |
113 | else | 113 | else |
114 | mp->m_dirnameops = &xfs_default_nameops; | 114 | mp->m_dirnameops = &xfs_default_nameops; |
115 | |||
116 | if (xfs_sb_version_hascrc(&mp->m_sb)) | ||
117 | mp->m_dir_inode_ops = &xfs_dir3_ops; | ||
118 | else if (xfs_sb_version_hasftype(&mp->m_sb)) | ||
119 | mp->m_dir_inode_ops = &xfs_dir2_ftype_ops; | ||
120 | else | ||
121 | mp->m_dir_inode_ops = &xfs_dir2_ops; | ||
115 | } | 122 | } |
116 | 123 | ||
117 | /* | 124 | /* |
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h index 9910401327d4..1909d9faff71 100644 --- a/fs/xfs/xfs_dir2.h +++ b/fs/xfs/xfs_dir2.h | |||
@@ -32,6 +32,20 @@ struct xfs_dir2_data_unused; | |||
32 | extern struct xfs_name xfs_name_dotdot; | 32 | extern struct xfs_name xfs_name_dotdot; |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * directory operations vector for encode/decode routines | ||
36 | */ | ||
37 | struct xfs_dir_ops { | ||
38 | int (*sf_entsize)(struct xfs_dir2_sf_hdr *hdr, int len); | ||
39 | struct xfs_dir2_sf_entry * | ||
40 | (*sf_nextentry)(struct xfs_dir2_sf_hdr *hdr, | ||
41 | struct xfs_dir2_sf_entry *sfep); | ||
42 | }; | ||
43 | |||
44 | extern const struct xfs_dir_ops xfs_dir2_ops; | ||
45 | extern const struct xfs_dir_ops xfs_dir2_ftype_ops; | ||
46 | extern const struct xfs_dir_ops xfs_dir3_ops; | ||
47 | |||
48 | /* | ||
35 | * Generic directory interface routines | 49 | * Generic directory interface routines |
36 | */ | 50 | */ |
37 | extern void xfs_dir_startup(void); | 51 | extern void xfs_dir_startup(void); |
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 9f3f83a5e2da..9d86b6f9e80f 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
@@ -1240,7 +1240,7 @@ xfs_dir2_sf_to_block( | |||
1240 | if (++i == sfp->count) | 1240 | if (++i == sfp->count) |
1241 | sfep = NULL; | 1241 | sfep = NULL; |
1242 | else | 1242 | else |
1243 | sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); | 1243 | sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
1244 | } | 1244 | } |
1245 | /* Done with the temporary buffer */ | 1245 | /* Done with the temporary buffer */ |
1246 | kmem_free(sfp); | 1246 | kmem_free(sfp); |
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index 45c9ce8cdb28..80333055df34 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c | |||
@@ -153,7 +153,7 @@ xfs_dir2_sf_getdents( | |||
153 | xfs_dir2_sf_get_offset(sfep)); | 153 | xfs_dir2_sf_get_offset(sfep)); |
154 | 154 | ||
155 | if (ctx->pos > off) { | 155 | if (ctx->pos > off) { |
156 | sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); | 156 | sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
157 | continue; | 157 | continue; |
158 | } | 158 | } |
159 | 159 | ||
@@ -163,7 +163,7 @@ xfs_dir2_sf_getdents( | |||
163 | if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, | 163 | if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, |
164 | xfs_dir3_get_dtype(mp, filetype))) | 164 | xfs_dir3_get_dtype(mp, filetype))) |
165 | return 0; | 165 | return 0; |
166 | sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); | 166 | sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
167 | } | 167 | } |
168 | 168 | ||
169 | ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & | 169 | ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & |
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index 8811ee5eaec6..73881c9f40d6 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c | |||
@@ -336,7 +336,7 @@ xfs_dir2_block_to_sf( | |||
336 | xfs_dir3_sfe_put_ftype(mp, sfp, sfep, | 336 | xfs_dir3_sfe_put_ftype(mp, sfp, sfep, |
337 | xfs_dir3_dirent_get_ftype(mp, dep)); | 337 | xfs_dir3_dirent_get_ftype(mp, dep)); |
338 | 338 | ||
339 | sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); | 339 | sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
340 | } | 340 | } |
341 | ptr += xfs_dir3_data_entsize(mp, dep->namelen); | 341 | ptr += xfs_dir3_data_entsize(mp, dep->namelen); |
342 | } | 342 | } |
@@ -389,7 +389,7 @@ xfs_dir2_sf_addname( | |||
389 | /* | 389 | /* |
390 | * Compute entry (and change in) size. | 390 | * Compute entry (and change in) size. |
391 | */ | 391 | */ |
392 | add_entsize = xfs_dir3_sf_entsize(dp->i_mount, sfp, args->namelen); | 392 | add_entsize = dp->d_ops->sf_entsize(sfp, args->namelen); |
393 | incr_isize = add_entsize; | 393 | incr_isize = add_entsize; |
394 | objchange = 0; | 394 | objchange = 0; |
395 | #if XFS_BIG_INUMS | 395 | #if XFS_BIG_INUMS |
@@ -483,8 +483,7 @@ xfs_dir2_sf_addname_easy( | |||
483 | /* | 483 | /* |
484 | * Grow the in-inode space. | 484 | * Grow the in-inode space. |
485 | */ | 485 | */ |
486 | xfs_idata_realloc(dp, | 486 | xfs_idata_realloc(dp, dp->d_ops->sf_entsize(sfp, args->namelen), |
487 | xfs_dir3_sf_entsize(dp->i_mount, sfp, args->namelen), | ||
488 | XFS_DATA_FORK); | 487 | XFS_DATA_FORK); |
489 | /* | 488 | /* |
490 | * Need to set up again due to realloc of the inode data. | 489 | * Need to set up again due to realloc of the inode data. |
@@ -563,7 +562,7 @@ xfs_dir2_sf_addname_hard( | |||
563 | eof = (char *)oldsfep == &buf[old_isize]; | 562 | eof = (char *)oldsfep == &buf[old_isize]; |
564 | !eof; | 563 | !eof; |
565 | offset = new_offset + xfs_dir3_data_entsize(mp, oldsfep->namelen), | 564 | offset = new_offset + xfs_dir3_data_entsize(mp, oldsfep->namelen), |
566 | oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep), | 565 | oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep), |
567 | eof = (char *)oldsfep == &buf[old_isize]) { | 566 | eof = (char *)oldsfep == &buf[old_isize]) { |
568 | new_offset = xfs_dir2_sf_get_offset(oldsfep); | 567 | new_offset = xfs_dir2_sf_get_offset(oldsfep); |
569 | if (offset + add_datasize <= new_offset) | 568 | if (offset + add_datasize <= new_offset) |
@@ -603,7 +602,7 @@ xfs_dir2_sf_addname_hard( | |||
603 | * If there's more left to copy, do that. | 602 | * If there's more left to copy, do that. |
604 | */ | 603 | */ |
605 | if (!eof) { | 604 | if (!eof) { |
606 | sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); | 605 | sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
607 | memcpy(sfep, oldsfep, old_isize - nbytes); | 606 | memcpy(sfep, oldsfep, old_isize - nbytes); |
608 | } | 607 | } |
609 | kmem_free(buf); | 608 | kmem_free(buf); |
@@ -653,7 +652,7 @@ xfs_dir2_sf_addname_pick( | |||
653 | holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); | 652 | holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); |
654 | offset = xfs_dir2_sf_get_offset(sfep) + | 653 | offset = xfs_dir2_sf_get_offset(sfep) + |
655 | xfs_dir3_data_entsize(mp, sfep->namelen); | 654 | xfs_dir3_data_entsize(mp, sfep->namelen); |
656 | sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep); | 655 | sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
657 | } | 656 | } |
658 | /* | 657 | /* |
659 | * Calculate data bytes used excluding the new entry, if this | 658 | * Calculate data bytes used excluding the new entry, if this |
@@ -719,7 +718,7 @@ xfs_dir2_sf_check( | |||
719 | 718 | ||
720 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); | 719 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); |
721 | i < sfp->count; | 720 | i < sfp->count; |
722 | i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep)) { | 721 | i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { |
723 | ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); | 722 | ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); |
724 | ino = xfs_dir3_sfe_get_ino(mp, sfp, sfep); | 723 | ino = xfs_dir3_sfe_get_ino(mp, sfp, sfep); |
725 | i8count += ino > XFS_DIR2_MAX_SHORT_INUM; | 724 | i8count += ino > XFS_DIR2_MAX_SHORT_INUM; |
@@ -848,7 +847,7 @@ xfs_dir2_sf_lookup( | |||
848 | */ | 847 | */ |
849 | ci_sfep = NULL; | 848 | ci_sfep = NULL; |
850 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; | 849 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; |
851 | i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) { | 850 | i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { |
852 | /* | 851 | /* |
853 | * Compare name and if it's an exact match, return the inode | 852 | * Compare name and if it's an exact match, return the inode |
854 | * number. If it's the first case-insensitive match, store the | 853 | * number. If it's the first case-insensitive match, store the |
@@ -917,7 +916,7 @@ xfs_dir2_sf_removename( | |||
917 | * Find the one we're deleting. | 916 | * Find the one we're deleting. |
918 | */ | 917 | */ |
919 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; | 918 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; |
920 | i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) { | 919 | i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { |
921 | if (xfs_da_compname(args, sfep->name, sfep->namelen) == | 920 | if (xfs_da_compname(args, sfep->name, sfep->namelen) == |
922 | XFS_CMP_EXACT) { | 921 | XFS_CMP_EXACT) { |
923 | ASSERT(xfs_dir3_sfe_get_ino(dp->i_mount, sfp, sfep) == | 922 | ASSERT(xfs_dir3_sfe_get_ino(dp->i_mount, sfp, sfep) == |
@@ -934,7 +933,7 @@ xfs_dir2_sf_removename( | |||
934 | * Calculate sizes. | 933 | * Calculate sizes. |
935 | */ | 934 | */ |
936 | byteoff = (int)((char *)sfep - (char *)sfp); | 935 | byteoff = (int)((char *)sfep - (char *)sfp); |
937 | entsize = xfs_dir3_sf_entsize(dp->i_mount, sfp, args->namelen); | 936 | entsize = dp->d_ops->sf_entsize(sfp, args->namelen); |
938 | newsize = oldsize - entsize; | 937 | newsize = oldsize - entsize; |
939 | /* | 938 | /* |
940 | * Copy the part if any after the removed entry, sliding it down. | 939 | * Copy the part if any after the removed entry, sliding it down. |
@@ -1051,7 +1050,7 @@ xfs_dir2_sf_replace( | |||
1051 | */ | 1050 | */ |
1052 | else { | 1051 | else { |
1053 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; | 1052 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; |
1054 | i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) { | 1053 | i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { |
1055 | if (xfs_da_compname(args, sfep->name, sfep->namelen) == | 1054 | if (xfs_da_compname(args, sfep->name, sfep->namelen) == |
1056 | XFS_CMP_EXACT) { | 1055 | XFS_CMP_EXACT) { |
1057 | #if XFS_BIG_INUMS || defined(DEBUG) | 1056 | #if XFS_BIG_INUMS || defined(DEBUG) |
@@ -1172,8 +1171,8 @@ xfs_dir2_sf_toino4( | |||
1172 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), | 1171 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), |
1173 | oldsfep = xfs_dir2_sf_firstentry(oldsfp); | 1172 | oldsfep = xfs_dir2_sf_firstentry(oldsfp); |
1174 | i < sfp->count; | 1173 | i < sfp->count; |
1175 | i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep), | 1174 | i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), |
1176 | oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep)) { | 1175 | oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { |
1177 | sfep->namelen = oldsfep->namelen; | 1176 | sfep->namelen = oldsfep->namelen; |
1178 | sfep->offset = oldsfep->offset; | 1177 | sfep->offset = oldsfep->offset; |
1179 | memcpy(sfep->name, oldsfep->name, sfep->namelen); | 1178 | memcpy(sfep->name, oldsfep->name, sfep->namelen); |
@@ -1251,8 +1250,8 @@ xfs_dir2_sf_toino8( | |||
1251 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), | 1250 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), |
1252 | oldsfep = xfs_dir2_sf_firstentry(oldsfp); | 1251 | oldsfep = xfs_dir2_sf_firstentry(oldsfp); |
1253 | i < sfp->count; | 1252 | i < sfp->count; |
1254 | i++, sfep = xfs_dir3_sf_nextentry(mp, sfp, sfep), | 1253 | i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), |
1255 | oldsfep = xfs_dir3_sf_nextentry(mp, oldsfp, oldsfep)) { | 1254 | oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { |
1256 | sfep->namelen = oldsfep->namelen; | 1255 | sfep->namelen = oldsfep->namelen; |
1257 | sfep->offset = oldsfep->offset; | 1256 | sfep->offset = oldsfep->offset; |
1258 | memcpy(sfep->name, oldsfep->name, sfep->namelen); | 1257 | memcpy(sfep->name, oldsfep->name, sfep->namelen); |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 66675877f38c..9e6efccbae04 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -49,6 +49,9 @@ typedef struct xfs_inode { | |||
49 | xfs_ifork_t *i_afp; /* attribute fork pointer */ | 49 | xfs_ifork_t *i_afp; /* attribute fork pointer */ |
50 | xfs_ifork_t i_df; /* data fork */ | 50 | xfs_ifork_t i_df; /* data fork */ |
51 | 51 | ||
52 | /* operations vectors */ | ||
53 | const struct xfs_dir_ops *d_ops; /* directory ops vector */ | ||
54 | |||
52 | /* Transaction and locking information. */ | 55 | /* Transaction and locking information. */ |
53 | struct xfs_inode_log_item *i_itemp; /* logging information */ | 56 | struct xfs_inode_log_item *i_itemp; /* logging information */ |
54 | mrlock_t i_lock; /* inode lock */ | 57 | mrlock_t i_lock; /* inode lock */ |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 718b62b0fe05..0493587ea6bc 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -1215,6 +1215,7 @@ xfs_setup_inode( | |||
1215 | else | 1215 | else |
1216 | inode->i_op = &xfs_dir_inode_operations; | 1216 | inode->i_op = &xfs_dir_inode_operations; |
1217 | inode->i_fop = &xfs_dir_file_operations; | 1217 | inode->i_fop = &xfs_dir_file_operations; |
1218 | ip->d_ops = ip->i_mount->m_dir_inode_ops; | ||
1218 | break; | 1219 | break; |
1219 | case S_IFLNK: | 1220 | case S_IFLNK: |
1220 | inode->i_op = &xfs_symlink_inode_operations; | 1221 | inode->i_op = &xfs_symlink_inode_operations; |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 1fa0584b5627..973397f66c6b 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -26,6 +26,7 @@ struct xfs_mru_cache; | |||
26 | struct xfs_nameops; | 26 | struct xfs_nameops; |
27 | struct xfs_ail; | 27 | struct xfs_ail; |
28 | struct xfs_quotainfo; | 28 | struct xfs_quotainfo; |
29 | struct xfs_dir_ops; | ||
29 | 30 | ||
30 | #ifdef HAVE_PERCPU_SB | 31 | #ifdef HAVE_PERCPU_SB |
31 | 32 | ||
@@ -148,6 +149,7 @@ typedef struct xfs_mount { | |||
148 | int m_dir_magicpct; /* 37% of the dir blocksize */ | 149 | int m_dir_magicpct; /* 37% of the dir blocksize */ |
149 | __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ | 150 | __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ |
150 | const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ | 151 | const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ |
152 | const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */ | ||
151 | int m_dirblksize; /* directory block sz--bytes */ | 153 | int m_dirblksize; /* directory block sz--bytes */ |
152 | int m_dirblkfsbs; /* directory block sz--fsbs */ | 154 | int m_dirblkfsbs; /* directory block sz--fsbs */ |
153 | xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ | 155 | xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */ |