xref: /onnv-gate/usr/src/uts/common/fs/zfs/zfs_log.c (revision 2237:45affe88ed99)
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 /*
221669Sperrin  * Copyright 2006 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  */
61789Sahrens uint64_t
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)
71789Sahrens 		return (0);
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 	return (seq);
90789Sahrens }
91789Sahrens 
92789Sahrens /*
93789Sahrens  * zfs_log_remove() handles both TX_REMOVE and TX_RMDIR transactions.
94789Sahrens  */
95789Sahrens uint64_t
96789Sahrens zfs_log_remove(zilog_t *zilog, dmu_tx_t *tx, int txtype,
97789Sahrens 	znode_t *dzp, char *name)
98789Sahrens {
99789Sahrens 	itx_t *itx;
100789Sahrens 	uint64_t seq;
101789Sahrens 	lr_remove_t *lr;
102789Sahrens 	size_t namesize = strlen(name) + 1;
103789Sahrens 
104789Sahrens 	if (zilog == NULL)
105789Sahrens 		return (0);
106789Sahrens 
107789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
108789Sahrens 	lr = (lr_remove_t *)&itx->itx_lr;
109789Sahrens 	lr->lr_doid = dzp->z_id;
110789Sahrens 	bcopy(name, (char *)(lr + 1), namesize);
111789Sahrens 
112789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
113789Sahrens 	dzp->z_last_itx = seq;
114789Sahrens 	return (seq);
115789Sahrens }
116789Sahrens 
117789Sahrens /*
118789Sahrens  * zfs_log_link() handles TX_LINK transactions.
119789Sahrens  */
120789Sahrens uint64_t
121789Sahrens zfs_log_link(zilog_t *zilog, dmu_tx_t *tx, int txtype,
122789Sahrens 	znode_t *dzp, znode_t *zp, char *name)
123789Sahrens {
124789Sahrens 	itx_t *itx;
125789Sahrens 	uint64_t seq;
126789Sahrens 	lr_link_t *lr;
127789Sahrens 	size_t namesize = strlen(name) + 1;
128789Sahrens 
129789Sahrens 	if (zilog == NULL)
130789Sahrens 		return (0);
131789Sahrens 
132789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize);
133789Sahrens 	lr = (lr_link_t *)&itx->itx_lr;
134789Sahrens 	lr->lr_doid = dzp->z_id;
135789Sahrens 	lr->lr_link_obj = zp->z_id;
136789Sahrens 	bcopy(name, (char *)(lr + 1), namesize);
137789Sahrens 
138789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
139789Sahrens 	dzp->z_last_itx = seq;
140789Sahrens 	zp->z_last_itx = seq;
141789Sahrens 	return (seq);
142789Sahrens }
143789Sahrens 
144789Sahrens /*
145789Sahrens  * zfs_log_symlink() handles TX_SYMLINK transactions.
146789Sahrens  */
147789Sahrens uint64_t
148789Sahrens zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, int txtype,
149789Sahrens 	znode_t *dzp, znode_t *zp, char *name, char *link)
150789Sahrens {
151789Sahrens 	itx_t *itx;
152789Sahrens 	uint64_t seq;
153789Sahrens 	lr_create_t *lr;
154789Sahrens 	size_t namesize = strlen(name) + 1;
155789Sahrens 	size_t linksize = strlen(link) + 1;
156789Sahrens 
157789Sahrens 	if (zilog == NULL)
158789Sahrens 		return (0);
159789Sahrens 
160789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + namesize + linksize);
161789Sahrens 	lr = (lr_create_t *)&itx->itx_lr;
162789Sahrens 	lr->lr_doid = dzp->z_id;
163789Sahrens 	lr->lr_foid = zp->z_id;
164789Sahrens 	lr->lr_mode = zp->z_phys->zp_mode;
165789Sahrens 	lr->lr_uid = zp->z_phys->zp_uid;
166789Sahrens 	lr->lr_gid = zp->z_phys->zp_gid;
167789Sahrens 	lr->lr_gen = zp->z_phys->zp_gen;
168789Sahrens 	lr->lr_crtime[0] = zp->z_phys->zp_crtime[0];
169789Sahrens 	lr->lr_crtime[1] = zp->z_phys->zp_crtime[1];
170789Sahrens 	bcopy(name, (char *)(lr + 1), namesize);
171789Sahrens 	bcopy(link, (char *)(lr + 1) + namesize, linksize);
172789Sahrens 
173789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
174789Sahrens 	dzp->z_last_itx = seq;
175789Sahrens 	zp->z_last_itx = seq;
176789Sahrens 	return (seq);
177789Sahrens }
178789Sahrens 
179789Sahrens /*
180789Sahrens  * zfs_log_rename() handles TX_RENAME transactions.
181789Sahrens  */
182789Sahrens uint64_t
183789Sahrens zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, int txtype,
184789Sahrens 	znode_t *sdzp, char *sname, znode_t *tdzp, char *dname, znode_t *szp)
185789Sahrens {
186789Sahrens 	itx_t *itx;
187789Sahrens 	uint64_t seq;
188789Sahrens 	lr_rename_t *lr;
189789Sahrens 	size_t snamesize = strlen(sname) + 1;
190789Sahrens 	size_t dnamesize = strlen(dname) + 1;
191789Sahrens 
192789Sahrens 	if (zilog == NULL)
193789Sahrens 		return (0);
194789Sahrens 
195789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + snamesize + dnamesize);
196789Sahrens 	lr = (lr_rename_t *)&itx->itx_lr;
197789Sahrens 	lr->lr_sdoid = sdzp->z_id;
198789Sahrens 	lr->lr_tdoid = tdzp->z_id;
199789Sahrens 	bcopy(sname, (char *)(lr + 1), snamesize);
200789Sahrens 	bcopy(dname, (char *)(lr + 1) + snamesize, dnamesize);
201789Sahrens 
202789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
203789Sahrens 	sdzp->z_last_itx = seq;
204789Sahrens 	tdzp->z_last_itx = seq;
205789Sahrens 	szp->z_last_itx = seq;
206789Sahrens 	return (seq);
207789Sahrens }
208789Sahrens 
209789Sahrens /*
210789Sahrens  * zfs_log_write() handles TX_WRITE transactions.
211789Sahrens  */
212*2237Smaybee ssize_t zfs_immediate_write_sz = 32768;
213789Sahrens 
214789Sahrens uint64_t
215789Sahrens zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
216789Sahrens 	znode_t *zp, offset_t off, ssize_t len, int ioflag, uio_t *uio)
217789Sahrens {
218789Sahrens 	itx_t *itx;
219789Sahrens 	uint64_t seq;
220789Sahrens 	lr_write_t *lr;
2211669Sperrin 	itx_wr_state_t write_state;
2221669Sperrin 	size_t dlen;
2231669Sperrin 	int err;
224789Sahrens 
225789Sahrens 	if (zilog == NULL || zp->z_reap)
226789Sahrens 		return (0);
227789Sahrens 
2281669Sperrin 	/*
2291669Sperrin 	 * Writes are handled in three different ways:
2301669Sperrin 	 *
2311669Sperrin 	 * WR_INDIRECT:
2321669Sperrin 	 *    If the write is greater than zfs_immediate_write_sz then
2331669Sperrin 	 *    later *if* we need to log the write then dmu_sync() is used
2341669Sperrin 	 *    to immediately write the block and it's block pointer is put
2351669Sperrin 	 *    in the log record.
2361669Sperrin 	 * WR_COPIED:
2371669Sperrin 	 *    If we know we'll immediately be committing the
2381669Sperrin 	 *    transaction (FDSYNC (O_DSYNC)), the we allocate a larger
2391669Sperrin 	 *    log record here for the data and copy the data in.
2401669Sperrin 	 * WR_NEED_COPY:
2411669Sperrin 	 *    Otherwise we don't allocate a buffer, and *if* we need to
2421669Sperrin 	 *    flush the write later then a buffer is allocated and
2431669Sperrin 	 *    we retrieve the data using the dmu.
2441669Sperrin 	 */
2451669Sperrin 	if (len > zfs_immediate_write_sz) {
2461669Sperrin 		dlen = 0;
2471669Sperrin 		write_state = WR_INDIRECT;
2481669Sperrin 	} else if (ioflag & FDSYNC) {
2491669Sperrin 		dlen = len;
2501669Sperrin 		write_state = WR_COPIED;
2511669Sperrin 	} else {
2521669Sperrin 		dlen = 0;
2531669Sperrin 		write_state = WR_NEED_COPY;
2541669Sperrin 	}
255789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + dlen);
2561669Sperrin 	if (write_state == WR_COPIED) {
257789Sahrens 		err = xcopyin(uio->uio_iov->iov_base - len,
2581669Sperrin 		    (char *)itx + offsetof(itx_t, itx_lr) + sizeof (*lr), len);
259789Sahrens 		/*
2601669Sperrin 		 * xcopyin shouldn't error as we've already successfully
261789Sahrens 		 * copied it to a dmu buffer. However if it does we'll get
262789Sahrens 		 * the data from the dmu later.
263789Sahrens 		 */
2641669Sperrin 		if (err) {
2651669Sperrin 			kmem_free(itx, offsetof(itx_t, itx_lr)
2661669Sperrin 			    + itx->itx_lr.lrc_reclen);
2671669Sperrin 			itx = zil_itx_create(txtype, sizeof (*lr));
2681669Sperrin 			write_state = WR_NEED_COPY;
2691669Sperrin 		}
270789Sahrens 	}
2711669Sperrin 	itx->itx_wr_state = write_state;
272789Sahrens 	lr = (lr_write_t *)&itx->itx_lr;
273789Sahrens 	lr->lr_foid = zp->z_id;
274789Sahrens 	lr->lr_offset = off;
275789Sahrens 	lr->lr_length = len;
276789Sahrens 	lr->lr_blkoff = 0;
277789Sahrens 	BP_ZERO(&lr->lr_blkptr);
278789Sahrens 
279789Sahrens 	itx->itx_private = zp->z_zfsvfs;
280789Sahrens 
281789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
282789Sahrens 	zp->z_last_itx = seq;
283789Sahrens 	return (seq);
284789Sahrens }
285789Sahrens 
286789Sahrens /*
287789Sahrens  * zfs_log_truncate() handles TX_TRUNCATE transactions.
288789Sahrens  */
289789Sahrens uint64_t
290789Sahrens zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype,
291789Sahrens 	znode_t *zp, uint64_t off, uint64_t len)
292789Sahrens {
293789Sahrens 	itx_t *itx;
294789Sahrens 	uint64_t seq;
295789Sahrens 	lr_truncate_t *lr;
296789Sahrens 
297789Sahrens 	if (zilog == NULL || zp->z_reap)
298789Sahrens 		return (0);
299789Sahrens 
300789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr));
301789Sahrens 	lr = (lr_truncate_t *)&itx->itx_lr;
302789Sahrens 	lr->lr_foid = zp->z_id;
303789Sahrens 	lr->lr_offset = off;
304789Sahrens 	lr->lr_length = len;
305789Sahrens 
306789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
307789Sahrens 	zp->z_last_itx = seq;
308789Sahrens 	return (seq);
309789Sahrens }
310789Sahrens 
311789Sahrens /*
312789Sahrens  * zfs_log_setattr() handles TX_SETATTR transactions.
313789Sahrens  */
314789Sahrens uint64_t
315789Sahrens zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
316789Sahrens 	znode_t *zp, vattr_t *vap, uint_t mask_applied)
317789Sahrens {
318789Sahrens 	itx_t *itx;
319789Sahrens 	uint64_t seq;
320789Sahrens 	lr_setattr_t *lr;
321789Sahrens 
322789Sahrens 	if (zilog == NULL || zp->z_reap)
323789Sahrens 		return (0);
324789Sahrens 
325789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr));
326789Sahrens 	lr = (lr_setattr_t *)&itx->itx_lr;
327789Sahrens 	lr->lr_foid = zp->z_id;
328789Sahrens 	lr->lr_mask = (uint64_t)mask_applied;
329789Sahrens 	lr->lr_mode = (uint64_t)vap->va_mode;
330789Sahrens 	lr->lr_uid = (uint64_t)vap->va_uid;
331789Sahrens 	lr->lr_gid = (uint64_t)vap->va_gid;
332789Sahrens 	lr->lr_size = (uint64_t)vap->va_size;
333789Sahrens 	ZFS_TIME_ENCODE(&vap->va_atime, lr->lr_atime);
334789Sahrens 	ZFS_TIME_ENCODE(&vap->va_mtime, lr->lr_mtime);
335789Sahrens 
336789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
337789Sahrens 	zp->z_last_itx = seq;
338789Sahrens 	return (seq);
339789Sahrens }
340789Sahrens 
341789Sahrens /*
342789Sahrens  * zfs_log_acl() handles TX_ACL transactions.
343789Sahrens  */
344789Sahrens uint64_t
345789Sahrens zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, int txtype,
346789Sahrens 	znode_t *zp, int aclcnt, ace_t *z_ace)
347789Sahrens {
348789Sahrens 	itx_t *itx;
349789Sahrens 	uint64_t seq;
350789Sahrens 	lr_acl_t *lr;
351789Sahrens 
352789Sahrens 	if (zilog == NULL || zp->z_reap)
353789Sahrens 		return (0);
354789Sahrens 
355789Sahrens 	itx = zil_itx_create(txtype, sizeof (*lr) + aclcnt * sizeof (ace_t));
356789Sahrens 	lr = (lr_acl_t *)&itx->itx_lr;
357789Sahrens 	lr->lr_foid = zp->z_id;
358789Sahrens 	lr->lr_aclcnt = (uint64_t)aclcnt;
359789Sahrens 	bcopy(z_ace, (ace_t *)(lr + 1), aclcnt * sizeof (ace_t));
360789Sahrens 
361789Sahrens 	seq = zil_itx_assign(zilog, itx, tx);
362789Sahrens 	zp->z_last_itx = seq;
363789Sahrens 	return (seq);
364789Sahrens }
365