xref: /onnv-gate/usr/src/uts/common/fs/zfs/zfs_log.c (revision 3638:6b28ebc717aa)
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 /*
223461Sahrens  * 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,
211*3638Sbillm 	znode_t *zp, offset_t off, ssize_t len, int ioflag)
212789Sahrens {
213789Sahrens 	itx_t *itx;
214789Sahrens 	uint64_t seq;
215789Sahrens 	lr_write_t *lr;
2161669Sperrin 	itx_wr_state_t write_state;
2171669Sperrin 	int err;
218789Sahrens 
2193461Sahrens 	if (zilog == NULL || zp->z_unlinked)
2202638Sperrin 		return;
221789Sahrens 
2221669Sperrin 	/*
2231669Sperrin 	 * Writes are handled in three different ways:
2241669Sperrin 	 *
2251669Sperrin 	 * WR_INDIRECT:
2261669Sperrin 	 *    If the write is greater than zfs_immediate_write_sz then
2271669Sperrin 	 *    later *if* we need to log the write then dmu_sync() is used
2281669Sperrin 	 *    to immediately write the block and it's block pointer is put
2291669Sperrin 	 *    in the log record.
2301669Sperrin 	 * WR_COPIED:
2311669Sperrin 	 *    If we know we'll immediately be committing the
2321669Sperrin 	 *    transaction (FDSYNC (O_DSYNC)), the we allocate a larger
2331669Sperrin 	 *    log record here for the data and copy the data in.
2341669Sperrin 	 * WR_NEED_COPY:
2351669Sperrin 	 *    Otherwise we don't allocate a buffer, and *if* we need to
2361669Sperrin 	 *    flush the write later then a buffer is allocated and
2371669Sperrin 	 *    we retrieve the data using the dmu.
2381669Sperrin 	 */
239*3638Sbillm 	if (len > zfs_immediate_write_sz)
2401669Sperrin 		write_state = WR_INDIRECT;
241*3638Sbillm 	else if (ioflag & FDSYNC)
2421669Sperrin 		write_state = WR_COPIED;
243*3638Sbillm 	else
2441669Sperrin 		write_state = WR_NEED_COPY;
245*3638Sbillm 
246*3638Sbillm 	itx = zil_itx_create(txtype, sizeof (*lr) +
247*3638Sbillm 	    (write_state == WR_COPIED ? len : 0));
248*3638Sbillm 	lr = (lr_write_t *)&itx->itx_lr;
2491669Sperrin 	if (write_state == WR_COPIED) {
250*3638Sbillm 		err = dmu_read(zp->z_zfsvfs->z_os, zp->z_id, off, len, lr + 1);
2511669Sperrin 		if (err) {
252*3638Sbillm 			kmem_free(itx, offsetof(itx_t, itx_lr) +
253*3638Sbillm 			    itx->itx_lr.lrc_reclen);
2541669Sperrin 			itx = zil_itx_create(txtype, sizeof (*lr));
255*3638Sbillm 			lr = (lr_write_t *)&itx->itx_lr;
2561669Sperrin 			write_state = WR_NEED_COPY;
2571669Sperrin 		}
258789Sahrens 	}
259*3638Sbillm 
2601669Sperrin 	itx->itx_wr_state = write_state;
261789Sahrens 	lr->lr_foid = zp->z_id;
262789Sahrens 	lr->lr_offset = off;
263789Sahrens 	lr->lr_length = len;
264789Sahrens 	lr->lr_blkoff = 0;
265789Sahrens 	BP_ZERO(&lr->lr_blkptr);
266789Sahrens 
267789Sahrens 	itx->itx_private = zp->z_zfsvfs;
268789Sahrens 
2693063Sperrin 	itx->itx_sync = (zp->z_sync_cnt != 0);
270789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
271789Sahrens 	zp->z_last_itx = seq;
272789Sahrens }
273789Sahrens 
274789Sahrens /*
275789Sahrens  * zfs_log_truncate() handles TX_TRUNCATE transactions.
276789Sahrens  */
2772638Sperrin void
278789Sahrens zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype,
279789Sahrens 	znode_t *zp, uint64_t off, uint64_t len)
280789Sahrens {
281789Sahrens 	itx_t *itx;
282789Sahrens 	uint64_t seq;
283789Sahrens 	lr_truncate_t *lr;
284789Sahrens 
2853461Sahrens 	if (zilog == NULL || zp->z_unlinked)
2862638Sperrin 		return;
287789Sahrens 
288789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr));
289789Sahrens 	lr = (lr_truncate_t *)&itx->itx_lr;
290789Sahrens 	lr->lr_foid = zp->z_id;
291789Sahrens 	lr->lr_offset = off;
292789Sahrens 	lr->lr_length = len;
293789Sahrens 
2943063Sperrin 	itx->itx_sync = (zp->z_sync_cnt != 0);
295789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
296789Sahrens 	zp->z_last_itx = seq;
297789Sahrens }
298789Sahrens 
299789Sahrens /*
300789Sahrens  * zfs_log_setattr() handles TX_SETATTR transactions.
301789Sahrens  */
3022638Sperrin void
303789Sahrens zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
304789Sahrens 	znode_t *zp, vattr_t *vap, uint_t mask_applied)
305789Sahrens {
306789Sahrens 	itx_t *itx;
307789Sahrens 	uint64_t seq;
308789Sahrens 	lr_setattr_t *lr;
309789Sahrens 
3103461Sahrens 	if (zilog == NULL || zp->z_unlinked)
3112638Sperrin 		return;
312789Sahrens 
313789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr));
314789Sahrens 	lr = (lr_setattr_t *)&itx->itx_lr;
315789Sahrens 	lr->lr_foid = zp->z_id;
316789Sahrens 	lr->lr_mask = (uint64_t)mask_applied;
317789Sahrens 	lr->lr_mode = (uint64_t)vap->va_mode;
318789Sahrens 	lr->lr_uid = (uint64_t)vap->va_uid;
319789Sahrens 	lr->lr_gid = (uint64_t)vap->va_gid;
320789Sahrens 	lr->lr_size = (uint64_t)vap->va_size;
321789Sahrens 	ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime);
322789Sahrens 	ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime);
323789Sahrens 
3243063Sperrin 	itx->itx_sync = (zp->z_sync_cnt != 0);
325789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
326789Sahrens 	zp->z_last_itx = seq;
327789Sahrens }
328789Sahrens 
329789Sahrens /*
330789Sahrens  * zfs_log_acl() handles TX_ACL transactions.
331789Sahrens  */
3322638Sperrin void
333789Sahrens zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, int txtype,
334789Sahrens 	znode_t *zp, int aclcnt, ace_t *z_ace)
335789Sahrens {
336789Sahrens 	itx_t *itx;
337789Sahrens 	uint64_t seq;
338789Sahrens 	lr_acl_t *lr;
339789Sahrens 
3403461Sahrens 	if (zilog == NULL || zp->z_unlinked)
3412638Sperrin 		return;
342789Sahrens 
343789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + aclcnt * sizeof (ace_t));
344789Sahrens 	lr = (lr_acl_t *)&itx->itx_lr;
345789Sahrens 	lr->lr_foid = zp->z_id;
346789Sahrens 	lr->lr_aclcnt = (uint64_t)aclcnt;
347789Sahrens 	bcopy(z_ace, (ace_t *)(lr + 1), aclcnt * sizeof (ace_t));
348789Sahrens 
3493063Sperrin 	itx->itx_sync = (zp->z_sync_cnt != 0);
350789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
351789Sahrens 	zp->z_last_itx = seq;
352789Sahrens }
353