aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2013-06-27 02:04:53 -0400
committerBen Myers <bpm@sgi.com>2013-06-27 14:34:12 -0400
commit3ebe7d2d73179c4874aee4f32e043eb5acd9fa0f (patch)
tree39bf0b8fac593d4051ebfbc7011a26423a8f90a4 /fs/xfs
parent5f6bed76c0c85cb4d04885a5de00b629deee550b (diff)
xfs: Inode create log items
Introduce the inode create log item type for logical inode create logging. Instead of logging the changes in buffers, pass the range to be initialised through the log by a new transaction type. This reduces the amount of log space required to record initialisation during allocation from about 128 bytes per inode to a small fixed amount per inode extent to be initialised. This requires a new log item type to track it through the log and the AIL. This is a relatively simple item - most callbacks are noops as this item has the same life cycle as the transaction. Signed-off-by: Dave Chinner <david@fromorbit.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/Makefile1
-rw-r--r--fs/xfs/xfs_icreate_item.c195
-rw-r--r--fs/xfs/xfs_icreate_item.h52
-rw-r--r--fs/xfs/xfs_log.h3
-rw-r--r--fs/xfs/xfs_super.c8
-rw-r--r--fs/xfs/xfs_trans.h4
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
43kmem_zone_t *xfs_icreate_zone; /* inode create item zone */
44
45static 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 */
55STATIC uint
56xfs_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 */
66STATIC void
67xfs_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. */
80STATIC void
81xfs_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. */
88STATIC void
89xfs_icreate_item_unpin(
90 struct xfs_log_item *lip,
91 int remove)
92{
93}
94
95STATIC void
96xfs_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 */
111STATIC xfs_lsn_t
112xfs_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 */
123STATIC uint
124xfs_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. */
133STATIC void
134xfs_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 */
143static 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 */
166void
167xfs_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 */
28struct 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 */
40struct xfs_icreate_item {
41 struct xfs_log_item ic_item;
42 struct xfs_icreate_log ic_format;
43};
44
45extern kmem_zone_t *xfs_icreate_zone; /* inode create item zone */
46
47void 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
93typedef struct xfs_log_iovec { 94typedef 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 \