xref: /illumos-gate/usr/src/uts/common/fs/zfs/zfs_log.c (revision 4bc0a2ef2b7ba50a7a717e7ddbf31472ad28e358)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/types.h>
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/sysmacros.h>
33 #include <sys/cmn_err.h>
34 #include <sys/kmem.h>
35 #include <sys/thread.h>
36 #include <sys/file.h>
37 #include <sys/vfs.h>
38 #include <sys/zfs_znode.h>
39 #include <sys/zfs_dir.h>
40 #include <sys/zil.h>
41 #include <sys/byteorder.h>
42 #include <sys/policy.h>
43 #include <sys/stat.h>
44 #include <sys/mode.h>
45 #include <sys/acl.h>
46 #include <sys/dmu.h>
47 #include <sys/spa.h>
48 #include <sys/ddi.h>
49 
50 /*
51  * All the functions in this file are used to construct the log entries
52  * to record transactions. They allocate * a intent log transaction
53  * structure (itx_t) and save within it all the information necessary to
54  * possibly replay the transaction. The itx is then assigned a sequence
55  * number and inserted in the in-memory list anchored in the zilog.
56  */
57 
58 /*
59  * zfs_log_create() is used to handle TX_CREATE, TX_MKDIR and TX_MKXATTR
60  * transactions.
61  */
62 uint64_t
63 zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, int txtype,
64 	znode_t *dzp, znode_t *zp, char *name)
65 {
66 	itx_t *itx;
67 	uint64_t seq;
68 	lr_create_t *lr;
69 	size_t namesize = strlen(name) + 1;
70 
71 	if (zilog == NULL)
72 		return (0);
73 
74 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
75 	lr = (lr_create_t *)&itx->itx_lr;
76 	lr->lr_doid = dzp->z_id;
77 	lr->lr_foid = zp->z_id;
78 	lr->lr_mode = zp->z_phys->zp_mode;
79 	lr->lr_uid = zp->z_phys->zp_uid;
80 	lr->lr_gid = zp->z_phys->zp_gid;
81 	lr->lr_gen = zp->z_phys->zp_gen;
82 	lr->lr_crtime[0] = zp->z_phys->zp_crtime[0];
83 	lr->lr_crtime[1] = zp->z_phys->zp_crtime[1];
84 	lr->lr_rdev = zp->z_phys->zp_rdev;
85 	bcopy(name, (char *)(lr + 1), namesize);
86 
87 	seq = zil_itx_assign(zilog, itx, tx);
88 	dzp->z_last_itx = seq;
89 	zp->z_last_itx = seq;
90 	return (seq);
91 }
92 
93 /*
94  * zfs_log_remove() handles both TX_REMOVE and TX_RMDIR transactions.
95  */
96 uint64_t
97 zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, int txtype,
98 	znode_t *dzp, char *name)
99 {
100 	itx_t *itx;
101 	uint64_t seq;
102 	lr_remove_t *lr;
103 	size_t namesize = strlen(name) + 1;
104 
105 	if (zilog == NULL)
106 		return (0);
107 
108 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
109 	lr = (lr_remove_t *)&itx->itx_lr;
110 	lr->lr_doid = dzp->z_id;
111 	bcopy(name, (char *)(lr + 1), namesize);
112 
113 	seq = zil_itx_assign(zilog, itx, tx);
114 	dzp->z_last_itx = seq;
115 	return (seq);
116 }
117 
118 /*
119  * zfs_log_link() handles TX_LINK transactions.
120  */
121 uint64_t
122 zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, int txtype,
123 	znode_t *dzp, znode_t *zp, char *name)
124 {
125 	itx_t *itx;
126 	uint64_t seq;
127 	lr_link_t *lr;
128 	size_t namesize = strlen(name) + 1;
129 
130 	if (zilog == NULL)
131 		return (0);
132 
133 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
134 	lr = (lr_link_t *)&itx->itx_lr;
135 	lr->lr_doid = dzp->z_id;
136 	lr->lr_link_obj = zp->z_id;
137 	bcopy(name, (char *)(lr + 1), namesize);
138 
139 	seq = zil_itx_assign(zilog, itx, tx);
140 	dzp->z_last_itx = seq;
141 	zp->z_last_itx = seq;
142 	return (seq);
143 }
144 
145 /*
146  * zfs_log_symlink() handles TX_SYMLINK transactions.
147  */
148 uint64_t
149 zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, int txtype,
150 	znode_t *dzp, znode_t *zp, char *name, char *link)
151 {
152 	itx_t *itx;
153 	uint64_t seq;
154 	lr_create_t *lr;
155 	size_t namesize = strlen(name) + 1;
156 	size_t linksize = strlen(link) + 1;
157 
158 	if (zilog == NULL)
159 		return (0);
160 
161 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize);
162 	lr = (lr_create_t *)&itx->itx_lr;
163 	lr->lr_doid = dzp->z_id;
164 	lr->lr_foid = zp->z_id;
165 	lr->lr_mode = zp->z_phys->zp_mode;
166 	lr->lr_uid = zp->z_phys->zp_uid;
167 	lr->lr_gid = zp->z_phys->zp_gid;
168 	lr->lr_gen = zp->z_phys->zp_gen;
169 	lr->lr_crtime[0] = zp->z_phys->zp_crtime[0];
170 	lr->lr_crtime[1] = zp->z_phys->zp_crtime[1];
171 	bcopy(name, (char *)(lr + 1), namesize);
172 	bcopy(link, (char *)(lr + 1) + namesize, linksize);
173 
174 	seq = zil_itx_assign(zilog, itx, tx);
175 	dzp->z_last_itx = seq;
176 	zp->z_last_itx = seq;
177 	return (seq);
178 }
179 
180 /*
181  * zfs_log_rename() handles TX_RENAME transactions.
182  */
183 uint64_t
184 zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, int txtype,
185 	znode_t *sdzp, char *sname, znode_t *tdzp, char *dname, znode_t *szp)
186 {
187 	itx_t *itx;
188 	uint64_t seq;
189 	lr_rename_t *lr;
190 	size_t snamesize = strlen(sname) + 1;
191 	size_t dnamesize = strlen(dname) + 1;
192 
193 	if (zilog == NULL)
194 		return (0);
195 
196 	itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize);
197 	lr = (lr_rename_t *)&itx->itx_lr;
198 	lr->lr_sdoid = sdzp->z_id;
199 	lr->lr_tdoid = tdzp->z_id;
200 	bcopy(sname, (char *)(lr + 1), snamesize);
201 	bcopy(dname, (char *)(lr + 1) + snamesize, dnamesize);
202 
203 	seq = zil_itx_assign(zilog, itx, tx);
204 	sdzp->z_last_itx = seq;
205 	tdzp->z_last_itx = seq;
206 	szp->z_last_itx = seq;
207 	return (seq);
208 }
209 
210 /*
211  * zfs_log_write() handles TX_WRITE transactions.
212  *
213  * We store data in the log buffers if it small enough.
214  * Otherwise we flush the data out via dmu_sync().
215  */
216 ssize_t zfs_immediate_write_sz = 65536;
217 
218 uint64_t
219 zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
220 	znode_t *zp, offset_t off, ssize_t len, int ioflag, uio_t *uio)
221 {
222 	itx_t *itx;
223 	uint64_t seq;
224 	lr_write_t *lr;
225 	int dlen, err;
226 
227 	if (zilog == NULL || zp->z_reap)
228 		return (0);
229 
230 	dlen = (len <= zfs_immediate_write_sz ? len : 0);
231 	itx = zil_itx_create(txtype, sizeof (*lr) + dlen);
232 	itx->itx_data_copied = 0;
233 	if ((ioflag & FDSYNC) && (dlen != 0)) {
234 		err = xcopyin(uio->uio_iov->iov_base - len,
235 		    (char *)itx + offsetof(itx_t, itx_lr) +  sizeof (*lr),
236 		    len);
237 		/*
238 		 * copyin shouldn't fault as we've already successfully
239 		 * copied it to a dmu buffer. However if it does we'll get
240 		 * the data from the dmu later.
241 		 */
242 		if (!err)
243 			itx->itx_data_copied = 1;
244 	}
245 	lr = (lr_write_t *)&itx->itx_lr;
246 	lr->lr_foid = zp->z_id;
247 	lr->lr_offset = off;
248 	lr->lr_length = len;
249 	lr->lr_blkoff = 0;
250 	BP_ZERO(&lr->lr_blkptr);
251 
252 	itx->itx_private = zp->z_zfsvfs;
253 
254 	seq = zil_itx_assign(zilog, itx, tx);
255 	zp->z_last_itx = seq;
256 	return (seq);
257 }
258 
259 /*
260  * zfs_log_truncate() handles TX_TRUNCATE transactions.
261  */
262 uint64_t
263 zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype,
264 	znode_t *zp, uint64_t off, uint64_t len)
265 {
266 	itx_t *itx;
267 	uint64_t seq;
268 	lr_truncate_t *lr;
269 
270 	if (zilog == NULL || zp->z_reap)
271 		return (0);
272 
273 	itx = zil_itx_create(txtype, sizeof (*lr));
274 	lr = (lr_truncate_t *)&itx->itx_lr;
275 	lr->lr_foid = zp->z_id;
276 	lr->lr_offset = off;
277 	lr->lr_length = len;
278 
279 	seq = zil_itx_assign(zilog, itx, tx);
280 	zp->z_last_itx = seq;
281 	return (seq);
282 }
283 
284 /*
285  * zfs_log_setattr() handles TX_SETATTR transactions.
286  */
287 uint64_t
288 zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
289 	znode_t *zp, vattr_t *vap, uint_t mask_applied)
290 {
291 	itx_t *itx;
292 	uint64_t seq;
293 	lr_setattr_t *lr;
294 
295 	if (zilog == NULL || zp->z_reap)
296 		return (0);
297 
298 	itx = zil_itx_create(txtype, sizeof (*lr));
299 	lr = (lr_setattr_t *)&itx->itx_lr;
300 	lr->lr_foid = zp->z_id;
301 	lr->lr_mask = (uint64_t)mask_applied;
302 	lr->lr_mode = (uint64_t)vap->va_mode;
303 	lr->lr_uid = (uint64_t)vap->va_uid;
304 	lr->lr_gid = (uint64_t)vap->va_gid;
305 	lr->lr_size = (uint64_t)vap->va_size;
306 	ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime);
307 	ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime);
308 
309 	seq = zil_itx_assign(zilog, itx, tx);
310 	zp->z_last_itx = seq;
311 	return (seq);
312 }
313 
314 /*
315  * zfs_log_acl() handles TX_ACL transactions.
316  */
317 uint64_t
318 zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, int txtype,
319 	znode_t *zp, int aclcnt, ace_t *z_ace)
320 {
321 	itx_t *itx;
322 	uint64_t seq;
323 	lr_acl_t *lr;
324 
325 	if (zilog == NULL || zp->z_reap)
326 		return (0);
327 
328 	itx = zil_itx_create(txtype, sizeof (*lr) + aclcnt * sizeof (ace_t));
329 	lr = (lr_acl_t *)&itx->itx_lr;
330 	lr->lr_foid = zp->z_id;
331 	lr->lr_aclcnt = (uint64_t)aclcnt;
332 	bcopy(z_ace, (ace_t *)(lr + 1), aclcnt * sizeof (ace_t));
333 
334 	seq = zil_itx_assign(zilog, itx, tx);
335 	zp->z_last_itx = seq;
336 	return (seq);
337 }
338