diff options
-rw-r--r-- | fs/xfs/Makefile | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_icreate_item.c | 195 | ||||
-rw-r--r-- | fs/xfs/xfs_icreate_item.h | 52 | ||||
-rw-r--r-- | fs/xfs/xfs_log.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.h | 4 |
6 files changed, 261 insertions, 2 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 6313b69b6644..4a4508023a3c 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile | |||
@@ -71,6 +71,7 @@ xfs-y += xfs_alloc.o \ | |||
71 | xfs_dir2_sf.o \ | 71 | xfs_dir2_sf.o \ |
72 | xfs_ialloc.o \ | 72 | xfs_ialloc.o \ |
73 | xfs_ialloc_btree.o \ | 73 | xfs_ialloc_btree.o \ |
74 | xfs_icreate_item.o \ | ||
74 | xfs_inode.o \ | 75 | xfs_inode.o \ |
75 | xfs_log_recover.o \ | 76 | xfs_log_recover.o \ |
76 | xfs_mount.o \ | 77 | xfs_mount.o \ |
diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c new file mode 100644 index 000000000000..7716a4e7375e --- /dev/null +++ b/fs/xfs/xfs_icreate_item.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2010, 2013 Dave Chinner | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_fs.h" | ||
20 | #include "xfs_types.h" | ||
21 | #include "xfs_bit.h" | ||
22 | #include "xfs_log.h" | ||
23 | #include "xfs_inum.h" | ||
24 | #include "xfs_trans.h" | ||
25 | #include "xfs_buf_item.h" | ||
26 | #include "xfs_sb.h" | ||
27 | #include "xfs_ag.h" | ||
28 | #include "xfs_dir2.h" | ||
29 | #include "xfs_mount.h" | ||
30 | #include "xfs_trans_priv.h" | ||
31 | #include "xfs_bmap_btree.h" | ||
32 | #include "xfs_alloc_btree.h" | ||
33 | #include "xfs_ialloc_btree.h" | ||
34 | #include "xfs_attr_sf.h" | ||
35 | #include "xfs_dinode.h" | ||
36 | #include "xfs_inode.h" | ||
37 | #include "xfs_inode_item.h" | ||
38 | #include "xfs_btree.h" | ||
39 | #include "xfs_ialloc.h" | ||
40 | #include "xfs_error.h" | ||
41 | #include "xfs_icreate_item.h" | ||
42 | |||
43 | kmem_zone_t *xfs_icreate_zone; /* inode create item zone */ | ||
44 | |||
45 | static inline struct xfs_icreate_item *ICR_ITEM(struct xfs_log_item *lip) | ||
46 | { | ||
47 | return container_of(lip, struct xfs_icreate_item, ic_item); | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * This returns the number of iovecs needed to log the given inode item. | ||
52 | * | ||
53 | * We only need one iovec for the icreate log structure. | ||
54 | */ | ||
55 | STATIC uint | ||
56 | xfs_icreate_item_size( | ||
57 | struct xfs_log_item *lip) | ||
58 | { | ||
59 | return 1; | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * This is called to fill in the vector of log iovecs for the | ||
64 | * given inode create log item. | ||
65 | */ | ||
66 | STATIC void | ||
67 | xfs_icreate_item_format( | ||
68 | struct xfs_log_item *lip, | ||
69 | struct xfs_log_iovec *log_vector) | ||
70 | { | ||
71 | struct xfs_icreate_item *icp = ICR_ITEM(lip); | ||
72 | |||
73 | log_vector->i_addr = (xfs_caddr_t)&icp->ic_format; | ||
74 | log_vector->i_len = sizeof(struct xfs_icreate_log); | ||
75 | log_vector->i_type = XLOG_REG_TYPE_ICREATE; | ||
76 | } | ||
77 | |||
78 | |||
79 | /* Pinning has no meaning for the create item, so just return. */ | ||
80 | STATIC void | ||
81 | xfs_icreate_item_pin( | ||
82 | struct xfs_log_item *lip) | ||
83 | { | ||
84 | } | ||
85 | |||
86 | |||
87 | /* pinning has no meaning for the create item, so just return. */ | ||
88 | STATIC void | ||
89 | xfs_icreate_item_unpin( | ||
90 | struct xfs_log_item *lip, | ||
91 | int remove) | ||
92 | { | ||
93 | } | ||
94 | |||
95 | STATIC void | ||
96 | xfs_icreate_item_unlock( | ||
97 | struct xfs_log_item *lip) | ||
98 | { | ||
99 | struct xfs_icreate_item *icp = ICR_ITEM(lip); | ||
100 | |||
101 | if (icp->ic_item.li_flags & XFS_LI_ABORTED) | ||
102 | kmem_zone_free(xfs_icreate_zone, icp); | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * Because we have ordered buffers being tracked in the AIL for the inode | ||
108 | * creation, we don't need the create item after this. Hence we can free | ||
109 | * the log item and return -1 to tell the caller we're done with the item. | ||
110 | */ | ||
111 | STATIC xfs_lsn_t | ||
112 | xfs_icreate_item_committed( | ||
113 | struct xfs_log_item *lip, | ||
114 | xfs_lsn_t lsn) | ||
115 | { | ||
116 | struct xfs_icreate_item *icp = ICR_ITEM(lip); | ||
117 | |||
118 | kmem_zone_free(xfs_icreate_zone, icp); | ||
119 | return (xfs_lsn_t)-1; | ||
120 | } | ||
121 | |||
122 | /* item can never get into the AIL */ | ||
123 | STATIC uint | ||
124 | xfs_icreate_item_push( | ||
125 | struct xfs_log_item *lip, | ||
126 | struct list_head *buffer_list) | ||
127 | { | ||
128 | ASSERT(0); | ||
129 | return XFS_ITEM_SUCCESS; | ||
130 | } | ||
131 | |||
132 | /* Ordered buffers do the dependency tracking here, so this does nothing. */ | ||
133 | STATIC void | ||
134 | xfs_icreate_item_committing( | ||
135 | struct xfs_log_item *lip, | ||
136 | xfs_lsn_t lsn) | ||
137 | { | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * This is the ops vector shared by all buf log items. | ||
142 | */ | ||
143 | static struct xfs_item_ops xfs_icreate_item_ops = { | ||
144 | .iop_size = xfs_icreate_item_size, | ||
145 | .iop_format = xfs_icreate_item_format, | ||
146 | .iop_pin = xfs_icreate_item_pin, | ||
147 | .iop_unpin = xfs_icreate_item_unpin, | ||
148 | .iop_push = xfs_icreate_item_push, | ||
149 | .iop_unlock = xfs_icreate_item_unlock, | ||
150 | .iop_committed = xfs_icreate_item_committed, | ||
151 | .iop_committing = xfs_icreate_item_committing, | ||
152 | }; | ||
153 | |||
154 | |||
155 | /* | ||
156 | * Initialize the inode log item for a newly allocated (in-core) inode. | ||
157 | * | ||
158 | * Inode extents can only reside within an AG. Hence specify the starting | ||
159 | * block for the inode chunk by offset within an AG as well as the | ||
160 | * length of the allocated extent. | ||
161 | * | ||
162 | * This joins the item to the transaction and marks it dirty so | ||
163 | * that we don't need a separate call to do this, nor does the | ||
164 | * caller need to know anything about the icreate item. | ||
165 | */ | ||
166 | void | ||
167 | xfs_icreate_log( | ||
168 | struct xfs_trans *tp, | ||
169 | xfs_agnumber_t agno, | ||
170 | xfs_agblock_t agbno, | ||
171 | unsigned int count, | ||
172 | unsigned int inode_size, | ||
173 | xfs_agblock_t length, | ||
174 | unsigned int generation) | ||
175 | { | ||
176 | struct xfs_icreate_item *icp; | ||
177 | |||
178 | icp = kmem_zone_zalloc(xfs_icreate_zone, KM_SLEEP); | ||
179 | |||
180 | xfs_log_item_init(tp->t_mountp, &icp->ic_item, XFS_LI_ICREATE, | ||
181 | &xfs_icreate_item_ops); | ||
182 | |||
183 | icp->ic_format.icl_type = XFS_LI_ICREATE; | ||
184 | icp->ic_format.icl_size = 1; /* single vector */ | ||
185 | icp->ic_format.icl_ag = cpu_to_be32(agno); | ||
186 | icp->ic_format.icl_agbno = cpu_to_be32(agbno); | ||
187 | icp->ic_format.icl_count = cpu_to_be32(count); | ||
188 | icp->ic_format.icl_isize = cpu_to_be32(inode_size); | ||
189 | icp->ic_format.icl_length = cpu_to_be32(length); | ||
190 | icp->ic_format.icl_gen = cpu_to_be32(generation); | ||
191 | |||
192 | xfs_trans_add_item(tp, &icp->ic_item); | ||
193 | tp->t_flags |= XFS_TRANS_DIRTY; | ||
194 | icp->ic_item.li_desc->lid_flags |= XFS_LID_DIRTY; | ||
195 | } | ||
diff --git a/fs/xfs/xfs_icreate_item.h b/fs/xfs/xfs_icreate_item.h new file mode 100644 index 000000000000..88ba8aa0bc41 --- /dev/null +++ b/fs/xfs/xfs_icreate_item.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2010, Dave Chinner | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef XFS_ICREATE_ITEM_H | ||
19 | #define XFS_ICREATE_ITEM_H 1 | ||
20 | |||
21 | /* | ||
22 | * on disk log item structure | ||
23 | * | ||
24 | * Log recovery assumes the first two entries are the type and size and they fit | ||
25 | * in 32 bits. Also in host order (ugh) so they have to be 32 bit aligned so | ||
26 | * decoding can be done correctly. | ||
27 | */ | ||
28 | struct xfs_icreate_log { | ||
29 | __uint16_t icl_type; /* type of log format structure */ | ||
30 | __uint16_t icl_size; /* size of log format structure */ | ||
31 | __be32 icl_ag; /* ag being allocated in */ | ||
32 | __be32 icl_agbno; /* start block of inode range */ | ||
33 | __be32 icl_count; /* number of inodes to initialise */ | ||
34 | __be32 icl_isize; /* size of inodes */ | ||
35 | __be32 icl_length; /* length of extent to initialise */ | ||
36 | __be32 icl_gen; /* inode generation number to use */ | ||
37 | }; | ||
38 | |||
39 | /* in memory log item structure */ | ||
40 | struct xfs_icreate_item { | ||
41 | struct xfs_log_item ic_item; | ||
42 | struct xfs_icreate_log ic_format; | ||
43 | }; | ||
44 | |||
45 | extern kmem_zone_t *xfs_icreate_zone; /* inode create item zone */ | ||
46 | |||
47 | void xfs_icreate_log(struct xfs_trans *tp, xfs_agnumber_t agno, | ||
48 | xfs_agblock_t agbno, unsigned int count, | ||
49 | unsigned int inode_size, xfs_agblock_t length, | ||
50 | unsigned int generation); | ||
51 | |||
52 | #endif /* XFS_ICREATE_ITEM_H */ | ||
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index b20918c554aa..fb630e496c12 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h | |||
@@ -88,7 +88,8 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) | |||
88 | #define XLOG_REG_TYPE_UNMOUNT 17 | 88 | #define XLOG_REG_TYPE_UNMOUNT 17 |
89 | #define XLOG_REG_TYPE_COMMIT 18 | 89 | #define XLOG_REG_TYPE_COMMIT 18 |
90 | #define XLOG_REG_TYPE_TRANSHDR 19 | 90 | #define XLOG_REG_TYPE_TRANSHDR 19 |
91 | #define XLOG_REG_TYPE_MAX 19 | 91 | #define XLOG_REG_TYPE_ICREATE 20 |
92 | #define XLOG_REG_TYPE_MAX 20 | ||
92 | 93 | ||
93 | typedef struct xfs_log_iovec { | 94 | typedef struct xfs_log_iovec { |
94 | void *i_addr; /* beginning address of region */ | 95 | void *i_addr; /* beginning address of region */ |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 14924099bcb8..30ef68f8a390 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include "xfs_inode_item.h" | 51 | #include "xfs_inode_item.h" |
52 | #include "xfs_icache.h" | 52 | #include "xfs_icache.h" |
53 | #include "xfs_trace.h" | 53 | #include "xfs_trace.h" |
54 | #include "xfs_icreate_item.h" | ||
54 | 55 | ||
55 | #include <linux/namei.h> | 56 | #include <linux/namei.h> |
56 | #include <linux/init.h> | 57 | #include <linux/init.h> |
@@ -1650,9 +1651,15 @@ xfs_init_zones(void) | |||
1650 | KM_ZONE_SPREAD, NULL); | 1651 | KM_ZONE_SPREAD, NULL); |
1651 | if (!xfs_ili_zone) | 1652 | if (!xfs_ili_zone) |
1652 | goto out_destroy_inode_zone; | 1653 | goto out_destroy_inode_zone; |
1654 | xfs_icreate_zone = kmem_zone_init(sizeof(struct xfs_icreate_item), | ||
1655 | "xfs_icr"); | ||
1656 | if (!xfs_icreate_zone) | ||
1657 | goto out_destroy_ili_zone; | ||
1653 | 1658 | ||
1654 | return 0; | 1659 | return 0; |
1655 | 1660 | ||
1661 | out_destroy_ili_zone: | ||
1662 | kmem_zone_destroy(xfs_ili_zone); | ||
1656 | out_destroy_inode_zone: | 1663 | out_destroy_inode_zone: |
1657 | kmem_zone_destroy(xfs_inode_zone); | 1664 | kmem_zone_destroy(xfs_inode_zone); |
1658 | out_destroy_efi_zone: | 1665 | out_destroy_efi_zone: |
@@ -1691,6 +1698,7 @@ xfs_destroy_zones(void) | |||
1691 | * destroy caches. | 1698 | * destroy caches. |
1692 | */ | 1699 | */ |
1693 | rcu_barrier(); | 1700 | rcu_barrier(); |
1701 | kmem_zone_destroy(xfs_icreate_zone); | ||
1694 | kmem_zone_destroy(xfs_ili_zone); | 1702 | kmem_zone_destroy(xfs_ili_zone); |
1695 | kmem_zone_destroy(xfs_inode_zone); | 1703 | kmem_zone_destroy(xfs_inode_zone); |
1696 | kmem_zone_destroy(xfs_efi_zone); | 1704 | kmem_zone_destroy(xfs_efi_zone); |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 822570ec605a..2b4946393e30 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -48,6 +48,7 @@ typedef struct xfs_trans_header { | |||
48 | #define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */ | 48 | #define XFS_LI_BUF 0x123c /* v2 bufs, variable sized inode bufs */ |
49 | #define XFS_LI_DQUOT 0x123d | 49 | #define XFS_LI_DQUOT 0x123d |
50 | #define XFS_LI_QUOTAOFF 0x123e | 50 | #define XFS_LI_QUOTAOFF 0x123e |
51 | #define XFS_LI_ICREATE 0x123f | ||
51 | 52 | ||
52 | #define XFS_LI_TYPE_DESC \ | 53 | #define XFS_LI_TYPE_DESC \ |
53 | { XFS_LI_EFI, "XFS_LI_EFI" }, \ | 54 | { XFS_LI_EFI, "XFS_LI_EFI" }, \ |
@@ -107,7 +108,8 @@ typedef struct xfs_trans_header { | |||
107 | #define XFS_TRANS_SWAPEXT 40 | 108 | #define XFS_TRANS_SWAPEXT 40 |
108 | #define XFS_TRANS_SB_COUNT 41 | 109 | #define XFS_TRANS_SB_COUNT 41 |
109 | #define XFS_TRANS_CHECKPOINT 42 | 110 | #define XFS_TRANS_CHECKPOINT 42 |
110 | #define XFS_TRANS_TYPE_MAX 42 | 111 | #define XFS_TRANS_ICREATE 43 |
112 | #define XFS_TRANS_TYPE_MAX 43 | ||
111 | /* new transaction types need to be reflected in xfs_logprint(8) */ | 113 | /* new transaction types need to be reflected in xfs_logprint(8) */ |
112 | 114 | ||
113 | #define XFS_TRANS_TYPES \ | 115 | #define XFS_TRANS_TYPES \ |