xref: /onnv-gate/usr/src/uts/common/fs/zfs/zfs_log.c (revision 3461:c19b22f347d6)
1789Sahrens /*
2789Sahrens  * CDDL HEADER START
3789Sahrens  *
4789Sahrens  * The contents of this file are subject to the terms of the
51669Sperrin  * Common Development and Distribution License (the "License").
61669Sperrin  * You may not use this file except in compliance with the License.
7789Sahrens  *
8789Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9789Sahrens  * or http://www.opensolaris.org/os/licensing.
10789Sahrens  * See the License for the specific language governing permissions
11789Sahrens  * and limitations under the License.
12789Sahrens  *
13789Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
14789Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15789Sahrens  * If applicable, add the following below this CDDL HEADER, with the
16789Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
17789Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
18789Sahrens  *
19789Sahrens  * CDDL HEADER END
20789Sahrens  */
21789Sahrens /*
22*3461Sahrens  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23789Sahrens  * Use is subject to license terms.
24789Sahrens  */
25789Sahrens 
26789Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
27789Sahrens 
28789Sahrens #include <sys/types.h>
29789Sahrens #include <sys/param.h>
30789Sahrens #include <sys/systm.h>
31789Sahrens #include <sys/sysmacros.h>
32789Sahrens #include <sys/cmn_err.h>
33789Sahrens #include <sys/kmem.h>
34789Sahrens #include <sys/thread.h>
35789Sahrens #include <sys/file.h>
36789Sahrens #include <sys/vfs.h>
37789Sahrens #include <sys/zfs_znode.h>
38789Sahrens #include <sys/zfs_dir.h>
39789Sahrens #include <sys/zil.h>
40789Sahrens #include <sys/byteorder.h>
41789Sahrens #include <sys/policy.h>
42789Sahrens #include <sys/stat.h>
43789Sahrens #include <sys/mode.h>
44789Sahrens #include <sys/acl.h>
45789Sahrens #include <sys/dmu.h>
46789Sahrens #include <sys/spa.h>
47789Sahrens #include <sys/ddi.h>
48789Sahrens 
49789Sahrens /*
50789Sahrens  * All the functions in this file are used to construct the log entries
51789Sahrens  * to record transactions. They allocate * a intent log transaction
52789Sahrens  * structure (itx_t) and save within it all the information necessary to
53789Sahrens  * possibly replay the transaction. The itx is then assigned a sequence
54789Sahrens  * number and inserted in the in-memory list anchored in the zilog.
55789Sahrens  */
56789Sahrens 
57789Sahrens /*
58789Sahrens  * zfs_log_create() is used to handle TX_CREATE, TX_MKDIR and TX_MKXATTR
59789Sahrens  * transactions.
60789Sahrens  */
612638Sperrin void
62789Sahrens zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, int txtype,
63789Sahrens 	znode_t *dzp, znode_t *zp, char *name)
64789Sahrens {
65789Sahrens 	itx_t *itx;
66789Sahrens 	uint64_t seq;
67789Sahrens 	lr_create_t *lr;
68789Sahrens 	size_t namesize = strlen(name) + 1;
69789Sahrens 
70789Sahrens 	if (zilog == NULL)
712638Sperrin 		return;
72789Sahrens 
73789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
74789Sahrens 	lr = (lr_create_t *)&itx->itx_lr;
75789Sahrens 	lr->lr_doid = dzp->z_id;
76789Sahrens 	lr->lr_foid = zp->z_id;
77789Sahrens 	lr->lr_mode = zp->z_phys->zp_mode;
78789Sahrens 	lr->lr_uid = zp->z_phys->zp_uid;
79789Sahrens 	lr->lr_gid = zp->z_phys->zp_gid;
80789Sahrens 	lr->lr_gen = zp->z_phys->zp_gen;
81789Sahrens 	lr->lr_crtime[0] = zp->z_phys->zp_crtime[0];
82789Sahrens 	lr->lr_crtime[1] = zp->z_phys->zp_crtime[1];
83789Sahrens 	lr->lr_rdev = zp->z_phys->zp_rdev;
84789Sahrens 	bcopy(name, (char *)(lr + 1), namesize);
85789Sahrens 
86789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
87789Sahrens 	dzp->z_last_itx = seq;
88789Sahrens 	zp->z_last_itx = seq;
89789Sahrens }
90789Sahrens 
91789Sahrens /*
92789Sahrens  * zfs_log_remove() handles both TX_REMOVE and TX_RMDIR transactions.
93789Sahrens  */
942638Sperrin void
95789Sahrens zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, int txtype,
96789Sahrens 	znode_t *dzp, char *name)
97789Sahrens {
98789Sahrens 	itx_t *itx;
99789Sahrens 	uint64_t seq;
100789Sahrens 	lr_remove_t *lr;
101789Sahrens 	size_t namesize = strlen(name) + 1;
102789Sahrens 
103789Sahrens 	if (zilog == NULL)
1042638Sperrin 		return;
105789Sahrens 
106789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
107789Sahrens 	lr = (lr_remove_t *)&itx->itx_lr;
108789Sahrens 	lr->lr_doid = dzp->z_id;
109789Sahrens 	bcopy(name, (char *)(lr + 1), namesize);
110789Sahrens 
111789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
112789Sahrens 	dzp->z_last_itx = seq;
113789Sahrens }
114789Sahrens 
115789Sahrens /*
116789Sahrens  * zfs_log_link() handles TX_LINK transactions.
117789Sahrens  */
1182638Sperrin void
119789Sahrens zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, int txtype,
120789Sahrens 	znode_t *dzp, znode_t *zp, char *name)
121789Sahrens {
122789Sahrens 	itx_t *itx;
123789Sahrens 	uint64_t seq;
124789Sahrens 	lr_link_t *lr;
125789Sahrens 	size_t namesize = strlen(name) + 1;
126789Sahrens 
127789Sahrens 	if (zilog == NULL)
1282638Sperrin 		return;
129789Sahrens 
130789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
131789Sahrens 	lr = (lr_link_t *)&itx->itx_lr;
132789Sahrens 	lr->lr_doid = dzp->z_id;
133789Sahrens 	lr->lr_link_obj = zp->z_id;
134789Sahrens 	bcopy(name, (char *)(lr + 1), namesize);
135789Sahrens 
136789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
137789Sahrens 	dzp->z_last_itx = seq;
138789Sahrens 	zp->z_last_itx = seq;
139789Sahrens }
140789Sahrens 
141789Sahrens /*
142789Sahrens  * zfs_log_symlink() handles TX_SYMLINK transactions.
143789Sahrens  */
1442638Sperrin void
145789Sahrens zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, int txtype,
146789Sahrens 	znode_t *dzp, znode_t *zp, char *name, char *link)
147789Sahrens {
148789Sahrens 	itx_t *itx;
149789Sahrens 	uint64_t seq;
150789Sahrens 	lr_create_t *lr;
151789Sahrens 	size_t namesize = strlen(name) + 1;
152789Sahrens 	size_t linksize = strlen(link) + 1;
153789Sahrens 
154789Sahrens 	if (zilog == NULL)
1552638Sperrin 		return;
156789Sahrens 
157789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize);
158789Sahrens 	lr = (lr_create_t *)&itx->itx_lr;
159789Sahrens 	lr->lr_doid = dzp->z_id;
160789Sahrens 	lr->lr_foid = zp->z_id;
161789Sahrens 	lr->lr_mode = zp->z_phys->zp_mode;
162789Sahrens 	lr->lr_uid = zp->z_phys->zp_uid;
163789Sahrens 	lr->lr_gid = zp->z_phys->zp_gid;
164789Sahrens 	lr->lr_gen = zp->z_phys->zp_gen;
165789Sahrens 	lr->lr_crtime[0] = zp->z_phys->zp_crtime[0];
166789Sahrens 	lr->lr_crtime[1] = zp->z_phys->zp_crtime[1];
167789Sahrens 	bcopy(name, (char *)(lr + 1), namesize);
168789Sahrens 	bcopy(link, (char *)(lr + 1) + namesize, linksize);
169789Sahrens 
170789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
171789Sahrens 	dzp->z_last_itx = seq;
172789Sahrens 	zp->z_last_itx = seq;
173789Sahrens }
174789Sahrens 
175789Sahrens /*
176789Sahrens  * zfs_log_rename() handles TX_RENAME transactions.
177789Sahrens  */
1782638Sperrin void
179789Sahrens zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, int txtype,
180789Sahrens 	znode_t *sdzp, char *sname, znode_t *tdzp, char *dname, znode_t *szp)
181789Sahrens {
182789Sahrens 	itx_t *itx;
183789Sahrens 	uint64_t seq;
184789Sahrens 	lr_rename_t *lr;
185789Sahrens 	size_t snamesize = strlen(sname) + 1;
186789Sahrens 	size_t dnamesize = strlen(dname) + 1;
187789Sahrens 
188789Sahrens 	if (zilog == NULL)
1892638Sperrin 		return;
190789Sahrens 
191789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize);
192789Sahrens 	lr = (lr_rename_t *)&itx->itx_lr;
193789Sahrens 	lr->lr_sdoid = sdzp->z_id;
194789Sahrens 	lr->lr_tdoid = tdzp->z_id;
195789Sahrens 	bcopy(sname, (char *)(lr + 1), snamesize);
196789Sahrens 	bcopy(dname, (char *)(lr + 1) + snamesize, dnamesize);
197789Sahrens 
198789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
199789Sahrens 	sdzp->z_last_itx = seq;
200789Sahrens 	tdzp->z_last_itx = seq;
201789Sahrens 	szp->z_last_itx = seq;
202789Sahrens }
203789Sahrens 
204789Sahrens /*
205789Sahrens  * zfs_log_write() handles TX_WRITE transactions.
206789Sahrens  */
2072237Smaybee ssize_t zfs_immediate_write_sz = 32768;
208789Sahrens 
2092638Sperrin void
210789Sahrens zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
211789Sahrens 	znode_t *zp, offset_t off, ssize_t len, int ioflag, uio_t *uio)
212789Sahrens {
213789Sahrens 	itx_t *itx;
214789Sahrens 	uint64_t seq;
215789Sahrens 	lr_write_t *lr;
2161669Sperrin 	itx_wr_state_t write_state;
2171669Sperrin 	size_t dlen;
2181669Sperrin 	int err;
219789Sahrens 
220*3461Sahrens 	if (zilog == NULL || zp->z_unlinked)
2212638Sperrin 		return;
222789Sahrens 
2231669Sperrin 	/*
2241669Sperrin 	 * Writes are handled in three different ways:
2251669Sperrin 	 *
2261669Sperrin 	 * WR_INDIRECT:
2271669Sperrin 	 *    If the write is greater than zfs_immediate_write_sz then
2281669Sperrin 	 *    later *if* we need to log the write then dmu_sync() is used
2291669Sperrin 	 *    to immediately write the block and it's block pointer is put
2301669Sperrin 	 *    in the log record.
2311669Sperrin 	 * WR_COPIED:
2321669Sperrin 	 *    If we know we'll immediately be committing the
2331669Sperrin 	 *    transaction (FDSYNC (O_DSYNC)), the we allocate a larger
2341669Sperrin 	 *    log record here for the data and copy the data in.
2351669Sperrin 	 * WR_NEED_COPY:
2361669Sperrin 	 *    Otherwise we don't allocate a buffer, and *if* we need to
2371669Sperrin 	 *    flush the write later then a buffer is allocated and
2381669Sperrin 	 *    we retrieve the data using the dmu.
2391669Sperrin 	 */
2401669Sperrin 	if (len > zfs_immediate_write_sz) {
2411669Sperrin 		dlen = 0;
2421669Sperrin 		write_state = WR_INDIRECT;
2431669Sperrin 	} else if (ioflag & FDSYNC) {
2441669Sperrin 		dlen = len;
2451669Sperrin 		write_state = WR_COPIED;
2461669Sperrin 	} else {
2471669Sperrin 		dlen = 0;
2481669Sperrin 		write_state = WR_NEED_COPY;
2491669Sperrin 	}
250789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + dlen);
2511669Sperrin 	if (write_state == WR_COPIED) {
252789Sahrens 		err = xcopyin(uio->uio_iov->iov_base - len,
2531669Sperrin 		    (char *)itx + offsetof(itx_t, itx_lr) + sizeof (*lr), len);
254789Sahrens 		/*
2551669Sperrin 		 * xcopyin shouldn't error as we've already successfully
256789Sahrens 		 * copied it to a dmu buffer. However if it does we'll get
257789Sahrens 		 * the data from the dmu later.
258789Sahrens 		 */
2591669Sperrin 		if (err) {
2601669Sperrin 			kmem_free(itx, offsetof(itx_t, itx_lr)
2611669Sperrin 			    + itx->itx_lr.lrc_reclen);
2621669Sperrin 			itx = zil_itx_create(txtype, sizeof (*lr));
2631669Sperrin 			write_state = WR_NEED_COPY;
2641669Sperrin 		}
265789Sahrens 	}
2661669Sperrin 	itx->itx_wr_state = write_state;
267789Sahrens 	lr = (lr_write_t *)&itx->itx_lr;
268789Sahrens 	lr->lr_foid = zp->z_id;
269789Sahrens 	lr->lr_offset = off;
270789Sahrens 	lr->lr_length = len;
271789Sahrens 	lr->lr_blkoff = 0;
272789Sahrens 	BP_ZERO(&lr->lr_blkptr);
273789Sahrens 
274789Sahrens 	itx->itx_private = zp->z_zfsvfs;
275789Sahrens 
2763063Sperrin 	itx->itx_sync = (zp->z_sync_cnt != 0);
277789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
278789Sahrens 	zp->z_last_itx = seq;
279789Sahrens }
280789Sahrens 
281789Sahrens /*
282789Sahrens  * zfs_log_truncate() handles TX_TRUNCATE transactions.
283789Sahrens  */
2842638Sperrin void
285789Sahrens zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype,
286789Sahrens 	znode_t *zp, uint64_t off, uint64_t len)
287789Sahrens {
288789Sahrens 	itx_t *itx;
289789Sahrens 	uint64_t seq;
290789Sahrens 	lr_truncate_t *lr;
291789Sahrens 
292*3461Sahrens 	if (zilog == NULL || zp->z_unlinked)
2932638Sperrin 		return;
294789Sahrens 
295789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr));
296789Sahrens 	lr = (lr_truncate_t *)&itx->itx_lr;
297789Sahrens 	lr->lr_foid = zp->z_id;
298789Sahrens 	lr->lr_offset = off;
299789Sahrens 	lr->lr_length = len;
300789Sahrens 
3013063Sperrin 	itx->itx_sync = (zp->z_sync_cnt != 0);
302789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
303789Sahrens 	zp->z_last_itx = seq;
304789Sahrens }
305789Sahrens 
306789Sahrens /*
307789Sahrens  * zfs_log_setattr() handles TX_SETATTR transactions.
308789Sahrens  */
3092638Sperrin void
310789Sahrens zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
311789Sahrens 	znode_t *zp, vattr_t *vap, uint_t mask_applied)
312789Sahrens {
313789Sahrens 	itx_t *itx;
314789Sahrens 	uint64_t seq;
315789Sahrens 	lr_setattr_t *lr;
316789Sahrens 
317*3461Sahrens 	if (zilog == NULL || zp->z_unlinked)
3182638Sperrin 		return;
319789Sahrens 
320789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr));
321789Sahrens 	lr = (lr_setattr_t *)&itx->itx_lr;
322789Sahrens 	lr->lr_foid = zp->z_id;
323789Sahrens 	lr->lr_mask = (uint64_t)mask_applied;
324789Sahrens 	lr->lr_mode = (uint64_t)vap->va_mode;
325789Sahrens 	lr->lr_uid = (uint64_t)vap->va_uid;
326789Sahrens 	lr->lr_gid = (uint64_t)vap->va_gid;
327789Sahrens 	lr->lr_size = (uint64_t)vap->va_size;
328789Sahrens 	ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime);
329789Sahrens 	ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime);
330789Sahrens 
3313063Sperrin 	itx->itx_sync = (zp->z_sync_cnt != 0);
332789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
333789Sahrens 	zp->z_last_itx = seq;
334789Sahrens }
335789Sahrens 
336789Sahrens /*
337789Sahrens  * zfs_log_acl() handles TX_ACL transactions.
338789Sahrens  */
3392638Sperrin void
340789Sahrens zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, int txtype,
341789Sahrens 	znode_t *zp, int aclcnt, ace_t *z_ace)
342789Sahrens {
343789Sahrens 	itx_t *itx;
344789Sahrens 	uint64_t seq;
345789Sahrens 	lr_acl_t *lr;
346789Sahrens 
347*3461Sahrens 	if (zilog == NULL || zp->z_unlinked)
3482638Sperrin 		return;
349789Sahrens 
350789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + aclcnt * sizeof (ace_t));
351789Sahrens 	lr = (lr_acl_t *)&itx->itx_lr;
352789Sahrens 	lr->lr_foid = zp->z_id;
353789Sahrens 	lr->lr_aclcnt = (uint64_t)aclcnt;
354789Sahrens 	bcopy(z_ace, (ace_t *)(lr + 1), aclcnt * sizeof (ace_t));
355789Sahrens 
3563063Sperrin 	itx->itx_sync = (zp->z_sync_cnt != 0);
357789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
358789Sahrens 	zp->z_last_itx = seq;
359789Sahrens }
360