1 // SPDX-License-Identifier: GPL-2.0 2 3 #include "bcachefs.h" 4 #include "acl.h" 5 #include "btree_update.h" 6 #include "dirent.h" 7 #include "fs-common.h" 8 #include "inode.h" 9 #include "xattr.h" 10 11 #include <linux/posix_acl.h> 12 13 int bch2_create_trans(struct btree_trans *trans, u64 dir_inum, 14 struct bch_inode_unpacked *dir_u, 15 struct bch_inode_unpacked *new_inode, 16 const struct qstr *name, 17 uid_t uid, gid_t gid, umode_t mode, dev_t rdev, 18 struct posix_acl *default_acl, 19 struct posix_acl *acl) 20 { 21 struct bch_fs *c = trans->c; 22 struct btree_iter *dir_iter = NULL; 23 struct btree_iter *inode_iter = NULL; 24 struct bch_hash_info hash = bch2_hash_info_init(c, new_inode); 25 u64 now = bch2_current_time(c); 26 u64 cpu = raw_smp_processor_id(); 27 u64 dir_offset = 0; 28 int ret; 29 30 dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT); 31 ret = PTR_ERR_OR_ZERO(dir_iter); 32 if (ret) 33 goto err; 34 35 bch2_inode_init_late(new_inode, now, uid, gid, mode, rdev, dir_u); 36 37 if (!name) 38 new_inode->bi_flags |= BCH_INODE_UNLINKED; 39 40 inode_iter = bch2_inode_create(trans, new_inode, U32_MAX, cpu); 41 ret = PTR_ERR_OR_ZERO(inode_iter); 42 if (ret) 43 goto err; 44 45 if (default_acl) { 46 ret = bch2_set_acl_trans(trans, new_inode, &hash, 47 default_acl, ACL_TYPE_DEFAULT); 48 if (ret) 49 goto err; 50 } 51 52 if (acl) { 53 ret = bch2_set_acl_trans(trans, new_inode, &hash, 54 acl, ACL_TYPE_ACCESS); 55 if (ret) 56 goto err; 57 } 58 59 if (name) { 60 struct bch_hash_info dir_hash = bch2_hash_info_init(c, dir_u); 61 dir_u->bi_mtime = dir_u->bi_ctime = now; 62 63 if (S_ISDIR(new_inode->bi_mode)) 64 dir_u->bi_nlink++; 65 66 ret = bch2_inode_write(trans, dir_iter, dir_u); 67 if (ret) 68 goto err; 69 70 ret = bch2_dirent_create(trans, dir_inum, &dir_hash, 71 mode_to_type(new_inode->bi_mode), 72 name, new_inode->bi_inum, 73 &dir_offset, 74 BCH_HASH_SET_MUST_CREATE); 75 if (ret) 76 goto err; 77 } 78 79 if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) { 80 new_inode->bi_dir = dir_u->bi_inum; 81 new_inode->bi_dir_offset = dir_offset; 82 } 83 84 /* XXX use bch2_btree_iter_set_snapshot() */ 85 inode_iter->snapshot = U32_MAX; 86 bch2_btree_iter_set_pos(inode_iter, SPOS(0, new_inode->bi_inum, U32_MAX)); 87 88 ret = bch2_btree_iter_traverse(inode_iter) ?: 89 bch2_inode_write(trans, inode_iter, new_inode); 90 err: 91 bch2_trans_iter_put(trans, inode_iter); 92 bch2_trans_iter_put(trans, dir_iter); 93 return ret; 94 } 95 96 int bch2_link_trans(struct btree_trans *trans, u64 dir_inum, 97 u64 inum, struct bch_inode_unpacked *dir_u, 98 struct bch_inode_unpacked *inode_u, const struct qstr *name) 99 { 100 struct bch_fs *c = trans->c; 101 struct btree_iter *dir_iter = NULL, *inode_iter = NULL; 102 struct bch_hash_info dir_hash; 103 u64 now = bch2_current_time(c); 104 u64 dir_offset = 0; 105 int ret; 106 107 inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT); 108 ret = PTR_ERR_OR_ZERO(inode_iter); 109 if (ret) 110 goto err; 111 112 inode_u->bi_ctime = now; 113 bch2_inode_nlink_inc(inode_u); 114 115 dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, 0); 116 ret = PTR_ERR_OR_ZERO(dir_iter); 117 if (ret) 118 goto err; 119 120 dir_u->bi_mtime = dir_u->bi_ctime = now; 121 122 dir_hash = bch2_hash_info_init(c, dir_u); 123 124 ret = bch2_dirent_create(trans, dir_inum, &dir_hash, 125 mode_to_type(inode_u->bi_mode), 126 name, inum, &dir_offset, 127 BCH_HASH_SET_MUST_CREATE); 128 if (ret) 129 goto err; 130 131 if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) { 132 inode_u->bi_dir = dir_inum; 133 inode_u->bi_dir_offset = dir_offset; 134 } 135 136 ret = bch2_inode_write(trans, dir_iter, dir_u) ?: 137 bch2_inode_write(trans, inode_iter, inode_u); 138 err: 139 bch2_trans_iter_put(trans, dir_iter); 140 bch2_trans_iter_put(trans, inode_iter); 141 return ret; 142 } 143 144 int bch2_unlink_trans(struct btree_trans *trans, 145 u64 dir_inum, struct bch_inode_unpacked *dir_u, 146 struct bch_inode_unpacked *inode_u, 147 const struct qstr *name) 148 { 149 struct bch_fs *c = trans->c; 150 struct btree_iter *dir_iter = NULL, *dirent_iter = NULL, 151 *inode_iter = NULL; 152 struct bch_hash_info dir_hash; 153 u64 inum, now = bch2_current_time(c); 154 struct bkey_s_c k; 155 int ret; 156 157 dir_iter = bch2_inode_peek(trans, dir_u, dir_inum, BTREE_ITER_INTENT); 158 ret = PTR_ERR_OR_ZERO(dir_iter); 159 if (ret) 160 goto err; 161 162 dir_hash = bch2_hash_info_init(c, dir_u); 163 164 dirent_iter = __bch2_dirent_lookup_trans(trans, dir_inum, &dir_hash, 165 name, BTREE_ITER_INTENT); 166 ret = PTR_ERR_OR_ZERO(dirent_iter); 167 if (ret) 168 goto err; 169 170 k = bch2_btree_iter_peek_slot(dirent_iter); 171 inum = le64_to_cpu(bkey_s_c_to_dirent(k).v->d_inum); 172 173 inode_iter = bch2_inode_peek(trans, inode_u, inum, BTREE_ITER_INTENT); 174 ret = PTR_ERR_OR_ZERO(inode_iter); 175 if (ret) 176 goto err; 177 178 if (inode_u->bi_dir == k.k->p.inode && 179 inode_u->bi_dir_offset == k.k->p.offset) { 180 inode_u->bi_dir = 0; 181 inode_u->bi_dir_offset = 0; 182 } 183 184 dir_u->bi_mtime = dir_u->bi_ctime = inode_u->bi_ctime = now; 185 dir_u->bi_nlink -= S_ISDIR(inode_u->bi_mode); 186 bch2_inode_nlink_dec(inode_u); 187 188 ret = (S_ISDIR(inode_u->bi_mode) 189 ? bch2_empty_dir_trans(trans, inum) 190 : 0) ?: 191 bch2_dirent_delete_at(trans, &dir_hash, dirent_iter) ?: 192 bch2_inode_write(trans, dir_iter, dir_u) ?: 193 bch2_inode_write(trans, inode_iter, inode_u); 194 err: 195 bch2_trans_iter_put(trans, inode_iter); 196 bch2_trans_iter_put(trans, dirent_iter); 197 bch2_trans_iter_put(trans, dir_iter); 198 return ret; 199 } 200 201 bool bch2_reinherit_attrs(struct bch_inode_unpacked *dst_u, 202 struct bch_inode_unpacked *src_u) 203 { 204 u64 src, dst; 205 unsigned id; 206 bool ret = false; 207 208 for (id = 0; id < Inode_opt_nr; id++) { 209 if (dst_u->bi_fields_set & (1 << id)) 210 continue; 211 212 src = bch2_inode_opt_get(src_u, id); 213 dst = bch2_inode_opt_get(dst_u, id); 214 215 if (src == dst) 216 continue; 217 218 bch2_inode_opt_set(dst_u, id, src); 219 ret = true; 220 } 221 222 return ret; 223 } 224 225 int bch2_rename_trans(struct btree_trans *trans, 226 u64 src_dir, struct bch_inode_unpacked *src_dir_u, 227 u64 dst_dir, struct bch_inode_unpacked *dst_dir_u, 228 struct bch_inode_unpacked *src_inode_u, 229 struct bch_inode_unpacked *dst_inode_u, 230 const struct qstr *src_name, 231 const struct qstr *dst_name, 232 enum bch_rename_mode mode) 233 { 234 struct bch_fs *c = trans->c; 235 struct btree_iter *src_dir_iter = NULL, *dst_dir_iter = NULL; 236 struct btree_iter *src_inode_iter = NULL, *dst_inode_iter = NULL; 237 struct bch_hash_info src_hash, dst_hash; 238 u64 src_inode, src_offset, dst_inode, dst_offset; 239 u64 now = bch2_current_time(c); 240 int ret; 241 242 src_dir_iter = bch2_inode_peek(trans, src_dir_u, src_dir, 243 BTREE_ITER_INTENT); 244 ret = PTR_ERR_OR_ZERO(src_dir_iter); 245 if (ret) 246 goto err; 247 248 src_hash = bch2_hash_info_init(c, src_dir_u); 249 250 if (dst_dir != src_dir) { 251 dst_dir_iter = bch2_inode_peek(trans, dst_dir_u, dst_dir, 252 BTREE_ITER_INTENT); 253 ret = PTR_ERR_OR_ZERO(dst_dir_iter); 254 if (ret) 255 goto err; 256 257 dst_hash = bch2_hash_info_init(c, dst_dir_u); 258 } else { 259 dst_dir_u = src_dir_u; 260 dst_hash = src_hash; 261 } 262 263 ret = bch2_dirent_rename(trans, 264 src_dir, &src_hash, 265 dst_dir, &dst_hash, 266 src_name, &src_inode, &src_offset, 267 dst_name, &dst_inode, &dst_offset, 268 mode); 269 if (ret) 270 goto err; 271 272 src_inode_iter = bch2_inode_peek(trans, src_inode_u, src_inode, 273 BTREE_ITER_INTENT); 274 ret = PTR_ERR_OR_ZERO(src_inode_iter); 275 if (ret) 276 goto err; 277 278 if (dst_inode) { 279 dst_inode_iter = bch2_inode_peek(trans, dst_inode_u, dst_inode, 280 BTREE_ITER_INTENT); 281 ret = PTR_ERR_OR_ZERO(dst_inode_iter); 282 if (ret) 283 goto err; 284 } 285 286 if (c->sb.version >= bcachefs_metadata_version_inode_backpointers) { 287 src_inode_u->bi_dir = dst_dir_u->bi_inum; 288 src_inode_u->bi_dir_offset = dst_offset; 289 290 if (mode == BCH_RENAME_EXCHANGE) { 291 dst_inode_u->bi_dir = src_dir_u->bi_inum; 292 dst_inode_u->bi_dir_offset = src_offset; 293 } 294 295 if (mode == BCH_RENAME_OVERWRITE && 296 dst_inode_u->bi_dir == dst_dir_u->bi_inum && 297 dst_inode_u->bi_dir_offset == src_offset) { 298 dst_inode_u->bi_dir = 0; 299 dst_inode_u->bi_dir_offset = 0; 300 } 301 } 302 303 if (mode == BCH_RENAME_OVERWRITE) { 304 if (S_ISDIR(src_inode_u->bi_mode) != 305 S_ISDIR(dst_inode_u->bi_mode)) { 306 ret = -ENOTDIR; 307 goto err; 308 } 309 310 if (S_ISDIR(dst_inode_u->bi_mode) && 311 bch2_empty_dir_trans(trans, dst_inode)) { 312 ret = -ENOTEMPTY; 313 goto err; 314 } 315 } 316 317 if (bch2_reinherit_attrs(src_inode_u, dst_dir_u) && 318 S_ISDIR(src_inode_u->bi_mode)) { 319 ret = -EXDEV; 320 goto err; 321 } 322 323 if (mode == BCH_RENAME_EXCHANGE && 324 bch2_reinherit_attrs(dst_inode_u, src_dir_u) && 325 S_ISDIR(dst_inode_u->bi_mode)) { 326 ret = -EXDEV; 327 goto err; 328 } 329 330 if (S_ISDIR(src_inode_u->bi_mode)) { 331 src_dir_u->bi_nlink--; 332 dst_dir_u->bi_nlink++; 333 } 334 335 if (dst_inode && S_ISDIR(dst_inode_u->bi_mode)) { 336 dst_dir_u->bi_nlink--; 337 src_dir_u->bi_nlink += mode == BCH_RENAME_EXCHANGE; 338 } 339 340 if (mode == BCH_RENAME_OVERWRITE) 341 bch2_inode_nlink_dec(dst_inode_u); 342 343 src_dir_u->bi_mtime = now; 344 src_dir_u->bi_ctime = now; 345 346 if (src_dir != dst_dir) { 347 dst_dir_u->bi_mtime = now; 348 dst_dir_u->bi_ctime = now; 349 } 350 351 src_inode_u->bi_ctime = now; 352 353 if (dst_inode) 354 dst_inode_u->bi_ctime = now; 355 356 ret = bch2_inode_write(trans, src_dir_iter, src_dir_u) ?: 357 (src_dir != dst_dir 358 ? bch2_inode_write(trans, dst_dir_iter, dst_dir_u) 359 : 0 ) ?: 360 bch2_inode_write(trans, src_inode_iter, src_inode_u) ?: 361 (dst_inode 362 ? bch2_inode_write(trans, dst_inode_iter, dst_inode_u) 363 : 0 ); 364 err: 365 bch2_trans_iter_put(trans, dst_inode_iter); 366 bch2_trans_iter_put(trans, src_inode_iter); 367 bch2_trans_iter_put(trans, dst_dir_iter); 368 bch2_trans_iter_put(trans, src_dir_iter); 369 return ret; 370 } 371