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