namei.c (16347B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/fs/hpfs/namei.c 4 * 5 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999 6 * 7 * adding & removing files & directories 8 */ 9#include <linux/sched.h> 10#include "hpfs_fn.h" 11 12static void hpfs_update_directory_times(struct inode *dir) 13{ 14 time64_t t = local_to_gmt(dir->i_sb, local_get_seconds(dir->i_sb)); 15 if (t == dir->i_mtime.tv_sec && 16 t == dir->i_ctime.tv_sec) 17 return; 18 dir->i_mtime.tv_sec = dir->i_ctime.tv_sec = t; 19 dir->i_mtime.tv_nsec = dir->i_ctime.tv_nsec = 0; 20 hpfs_write_inode_nolock(dir); 21} 22 23static int hpfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, 24 struct dentry *dentry, umode_t mode) 25{ 26 const unsigned char *name = dentry->d_name.name; 27 unsigned len = dentry->d_name.len; 28 struct quad_buffer_head qbh0; 29 struct buffer_head *bh; 30 struct hpfs_dirent *de; 31 struct fnode *fnode; 32 struct dnode *dnode; 33 struct inode *result; 34 fnode_secno fno; 35 dnode_secno dno; 36 int r; 37 struct hpfs_dirent dee; 38 int err; 39 if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err; 40 hpfs_lock(dir->i_sb); 41 err = -ENOSPC; 42 fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh); 43 if (!fnode) 44 goto bail; 45 dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0); 46 if (!dnode) 47 goto bail1; 48 memset(&dee, 0, sizeof dee); 49 dee.directory = 1; 50 if (!(mode & 0222)) dee.read_only = 1; 51 /*dee.archive = 0;*/ 52 dee.hidden = name[0] == '.'; 53 dee.fnode = cpu_to_le32(fno); 54 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb)); 55 result = new_inode(dir->i_sb); 56 if (!result) 57 goto bail2; 58 hpfs_init_inode(result); 59 result->i_ino = fno; 60 hpfs_i(result)->i_parent_dir = dir->i_ino; 61 hpfs_i(result)->i_dno = dno; 62 result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date)); 63 result->i_ctime.tv_nsec = 0; 64 result->i_mtime.tv_nsec = 0; 65 result->i_atime.tv_nsec = 0; 66 hpfs_i(result)->i_ea_size = 0; 67 result->i_mode |= S_IFDIR; 68 result->i_op = &hpfs_dir_iops; 69 result->i_fop = &hpfs_dir_ops; 70 result->i_blocks = 4; 71 result->i_size = 2048; 72 set_nlink(result, 2); 73 if (dee.read_only) 74 result->i_mode &= ~0222; 75 76 r = hpfs_add_dirent(dir, name, len, &dee); 77 if (r == 1) 78 goto bail3; 79 if (r == -1) { 80 err = -EEXIST; 81 goto bail3; 82 } 83 fnode->len = len; 84 memcpy(fnode->name, name, len > 15 ? 15 : len); 85 fnode->up = cpu_to_le32(dir->i_ino); 86 fnode->flags |= FNODE_dir; 87 fnode->btree.n_free_nodes = 7; 88 fnode->btree.n_used_nodes = 1; 89 fnode->btree.first_free = cpu_to_le16(0x14); 90 fnode->u.external[0].disk_secno = cpu_to_le32(dno); 91 fnode->u.external[0].file_secno = cpu_to_le32(-1); 92 dnode->root_dnode = 1; 93 dnode->up = cpu_to_le32(fno); 94 de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0); 95 de->creation_date = de->write_date = de->read_date = cpu_to_le32(local_get_seconds(dir->i_sb)); 96 if (!(mode & 0222)) de->read_only = 1; 97 de->first = de->directory = 1; 98 /*de->hidden = de->system = 0;*/ 99 de->fnode = cpu_to_le32(fno); 100 mark_buffer_dirty(bh); 101 brelse(bh); 102 hpfs_mark_4buffers_dirty(&qbh0); 103 hpfs_brelse4(&qbh0); 104 inc_nlink(dir); 105 insert_inode_hash(result); 106 107 if (!uid_eq(result->i_uid, current_fsuid()) || 108 !gid_eq(result->i_gid, current_fsgid()) || 109 result->i_mode != (mode | S_IFDIR)) { 110 result->i_uid = current_fsuid(); 111 result->i_gid = current_fsgid(); 112 result->i_mode = mode | S_IFDIR; 113 hpfs_write_inode_nolock(result); 114 } 115 hpfs_update_directory_times(dir); 116 d_instantiate(dentry, result); 117 hpfs_unlock(dir->i_sb); 118 return 0; 119bail3: 120 iput(result); 121bail2: 122 hpfs_brelse4(&qbh0); 123 hpfs_free_dnode(dir->i_sb, dno); 124bail1: 125 brelse(bh); 126 hpfs_free_sectors(dir->i_sb, fno, 1); 127bail: 128 hpfs_unlock(dir->i_sb); 129 return err; 130} 131 132static int hpfs_create(struct user_namespace *mnt_userns, struct inode *dir, 133 struct dentry *dentry, umode_t mode, bool excl) 134{ 135 const unsigned char *name = dentry->d_name.name; 136 unsigned len = dentry->d_name.len; 137 struct inode *result = NULL; 138 struct buffer_head *bh; 139 struct fnode *fnode; 140 fnode_secno fno; 141 int r; 142 struct hpfs_dirent dee; 143 int err; 144 if ((err = hpfs_chk_name(name, &len))) 145 return err==-ENOENT ? -EINVAL : err; 146 hpfs_lock(dir->i_sb); 147 err = -ENOSPC; 148 fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh); 149 if (!fnode) 150 goto bail; 151 memset(&dee, 0, sizeof dee); 152 if (!(mode & 0222)) dee.read_only = 1; 153 dee.archive = 1; 154 dee.hidden = name[0] == '.'; 155 dee.fnode = cpu_to_le32(fno); 156 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb)); 157 158 result = new_inode(dir->i_sb); 159 if (!result) 160 goto bail1; 161 162 hpfs_init_inode(result); 163 result->i_ino = fno; 164 result->i_mode |= S_IFREG; 165 result->i_mode &= ~0111; 166 result->i_op = &hpfs_file_iops; 167 result->i_fop = &hpfs_file_ops; 168 set_nlink(result, 1); 169 hpfs_i(result)->i_parent_dir = dir->i_ino; 170 result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date)); 171 result->i_ctime.tv_nsec = 0; 172 result->i_mtime.tv_nsec = 0; 173 result->i_atime.tv_nsec = 0; 174 hpfs_i(result)->i_ea_size = 0; 175 if (dee.read_only) 176 result->i_mode &= ~0222; 177 result->i_blocks = 1; 178 result->i_size = 0; 179 result->i_data.a_ops = &hpfs_aops; 180 hpfs_i(result)->mmu_private = 0; 181 182 r = hpfs_add_dirent(dir, name, len, &dee); 183 if (r == 1) 184 goto bail2; 185 if (r == -1) { 186 err = -EEXIST; 187 goto bail2; 188 } 189 fnode->len = len; 190 memcpy(fnode->name, name, len > 15 ? 15 : len); 191 fnode->up = cpu_to_le32(dir->i_ino); 192 mark_buffer_dirty(bh); 193 brelse(bh); 194 195 insert_inode_hash(result); 196 197 if (!uid_eq(result->i_uid, current_fsuid()) || 198 !gid_eq(result->i_gid, current_fsgid()) || 199 result->i_mode != (mode | S_IFREG)) { 200 result->i_uid = current_fsuid(); 201 result->i_gid = current_fsgid(); 202 result->i_mode = mode | S_IFREG; 203 hpfs_write_inode_nolock(result); 204 } 205 hpfs_update_directory_times(dir); 206 d_instantiate(dentry, result); 207 hpfs_unlock(dir->i_sb); 208 return 0; 209 210bail2: 211 iput(result); 212bail1: 213 brelse(bh); 214 hpfs_free_sectors(dir->i_sb, fno, 1); 215bail: 216 hpfs_unlock(dir->i_sb); 217 return err; 218} 219 220static int hpfs_mknod(struct user_namespace *mnt_userns, struct inode *dir, 221 struct dentry *dentry, umode_t mode, dev_t rdev) 222{ 223 const unsigned char *name = dentry->d_name.name; 224 unsigned len = dentry->d_name.len; 225 struct buffer_head *bh; 226 struct fnode *fnode; 227 fnode_secno fno; 228 int r; 229 struct hpfs_dirent dee; 230 struct inode *result = NULL; 231 int err; 232 if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err; 233 if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM; 234 hpfs_lock(dir->i_sb); 235 err = -ENOSPC; 236 fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh); 237 if (!fnode) 238 goto bail; 239 memset(&dee, 0, sizeof dee); 240 if (!(mode & 0222)) dee.read_only = 1; 241 dee.archive = 1; 242 dee.hidden = name[0] == '.'; 243 dee.fnode = cpu_to_le32(fno); 244 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb)); 245 246 result = new_inode(dir->i_sb); 247 if (!result) 248 goto bail1; 249 250 hpfs_init_inode(result); 251 result->i_ino = fno; 252 hpfs_i(result)->i_parent_dir = dir->i_ino; 253 result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date)); 254 result->i_ctime.tv_nsec = 0; 255 result->i_mtime.tv_nsec = 0; 256 result->i_atime.tv_nsec = 0; 257 hpfs_i(result)->i_ea_size = 0; 258 result->i_uid = current_fsuid(); 259 result->i_gid = current_fsgid(); 260 set_nlink(result, 1); 261 result->i_size = 0; 262 result->i_blocks = 1; 263 init_special_inode(result, mode, rdev); 264 265 r = hpfs_add_dirent(dir, name, len, &dee); 266 if (r == 1) 267 goto bail2; 268 if (r == -1) { 269 err = -EEXIST; 270 goto bail2; 271 } 272 fnode->len = len; 273 memcpy(fnode->name, name, len > 15 ? 15 : len); 274 fnode->up = cpu_to_le32(dir->i_ino); 275 mark_buffer_dirty(bh); 276 277 insert_inode_hash(result); 278 279 hpfs_write_inode_nolock(result); 280 hpfs_update_directory_times(dir); 281 d_instantiate(dentry, result); 282 brelse(bh); 283 hpfs_unlock(dir->i_sb); 284 return 0; 285bail2: 286 iput(result); 287bail1: 288 brelse(bh); 289 hpfs_free_sectors(dir->i_sb, fno, 1); 290bail: 291 hpfs_unlock(dir->i_sb); 292 return err; 293} 294 295static int hpfs_symlink(struct user_namespace *mnt_userns, struct inode *dir, 296 struct dentry *dentry, const char *symlink) 297{ 298 const unsigned char *name = dentry->d_name.name; 299 unsigned len = dentry->d_name.len; 300 struct buffer_head *bh; 301 struct fnode *fnode; 302 fnode_secno fno; 303 int r; 304 struct hpfs_dirent dee; 305 struct inode *result; 306 int err; 307 if ((err = hpfs_chk_name(name, &len))) return err==-ENOENT ? -EINVAL : err; 308 hpfs_lock(dir->i_sb); 309 if (hpfs_sb(dir->i_sb)->sb_eas < 2) { 310 hpfs_unlock(dir->i_sb); 311 return -EPERM; 312 } 313 err = -ENOSPC; 314 fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh); 315 if (!fnode) 316 goto bail; 317 memset(&dee, 0, sizeof dee); 318 dee.archive = 1; 319 dee.hidden = name[0] == '.'; 320 dee.fnode = cpu_to_le32(fno); 321 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb)); 322 323 result = new_inode(dir->i_sb); 324 if (!result) 325 goto bail1; 326 result->i_ino = fno; 327 hpfs_init_inode(result); 328 hpfs_i(result)->i_parent_dir = dir->i_ino; 329 result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, le32_to_cpu(dee.creation_date)); 330 result->i_ctime.tv_nsec = 0; 331 result->i_mtime.tv_nsec = 0; 332 result->i_atime.tv_nsec = 0; 333 hpfs_i(result)->i_ea_size = 0; 334 result->i_mode = S_IFLNK | 0777; 335 result->i_uid = current_fsuid(); 336 result->i_gid = current_fsgid(); 337 result->i_blocks = 1; 338 set_nlink(result, 1); 339 result->i_size = strlen(symlink); 340 inode_nohighmem(result); 341 result->i_op = &page_symlink_inode_operations; 342 result->i_data.a_ops = &hpfs_symlink_aops; 343 344 r = hpfs_add_dirent(dir, name, len, &dee); 345 if (r == 1) 346 goto bail2; 347 if (r == -1) { 348 err = -EEXIST; 349 goto bail2; 350 } 351 fnode->len = len; 352 memcpy(fnode->name, name, len > 15 ? 15 : len); 353 fnode->up = cpu_to_le32(dir->i_ino); 354 hpfs_set_ea(result, fnode, "SYMLINK", symlink, strlen(symlink)); 355 mark_buffer_dirty(bh); 356 brelse(bh); 357 358 insert_inode_hash(result); 359 360 hpfs_write_inode_nolock(result); 361 hpfs_update_directory_times(dir); 362 d_instantiate(dentry, result); 363 hpfs_unlock(dir->i_sb); 364 return 0; 365bail2: 366 iput(result); 367bail1: 368 brelse(bh); 369 hpfs_free_sectors(dir->i_sb, fno, 1); 370bail: 371 hpfs_unlock(dir->i_sb); 372 return err; 373} 374 375static int hpfs_unlink(struct inode *dir, struct dentry *dentry) 376{ 377 const unsigned char *name = dentry->d_name.name; 378 unsigned len = dentry->d_name.len; 379 struct quad_buffer_head qbh; 380 struct hpfs_dirent *de; 381 struct inode *inode = d_inode(dentry); 382 dnode_secno dno; 383 int r; 384 int err; 385 386 hpfs_lock(dir->i_sb); 387 hpfs_adjust_length(name, &len); 388 389 err = -ENOENT; 390 de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh); 391 if (!de) 392 goto out; 393 394 err = -EPERM; 395 if (de->first) 396 goto out1; 397 398 err = -EISDIR; 399 if (de->directory) 400 goto out1; 401 402 r = hpfs_remove_dirent(dir, dno, de, &qbh, 1); 403 switch (r) { 404 case 1: 405 hpfs_error(dir->i_sb, "there was error when removing dirent"); 406 err = -EFSERROR; 407 break; 408 case 2: /* no space for deleting */ 409 err = -ENOSPC; 410 break; 411 default: 412 drop_nlink(inode); 413 err = 0; 414 } 415 goto out; 416 417out1: 418 hpfs_brelse4(&qbh); 419out: 420 if (!err) 421 hpfs_update_directory_times(dir); 422 hpfs_unlock(dir->i_sb); 423 return err; 424} 425 426static int hpfs_rmdir(struct inode *dir, struct dentry *dentry) 427{ 428 const unsigned char *name = dentry->d_name.name; 429 unsigned len = dentry->d_name.len; 430 struct quad_buffer_head qbh; 431 struct hpfs_dirent *de; 432 struct inode *inode = d_inode(dentry); 433 dnode_secno dno; 434 int n_items = 0; 435 int err; 436 int r; 437 438 hpfs_adjust_length(name, &len); 439 hpfs_lock(dir->i_sb); 440 err = -ENOENT; 441 de = map_dirent(dir, hpfs_i(dir)->i_dno, name, len, &dno, &qbh); 442 if (!de) 443 goto out; 444 445 err = -EPERM; 446 if (de->first) 447 goto out1; 448 449 err = -ENOTDIR; 450 if (!de->directory) 451 goto out1; 452 453 hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items); 454 err = -ENOTEMPTY; 455 if (n_items) 456 goto out1; 457 458 r = hpfs_remove_dirent(dir, dno, de, &qbh, 1); 459 switch (r) { 460 case 1: 461 hpfs_error(dir->i_sb, "there was error when removing dirent"); 462 err = -EFSERROR; 463 break; 464 case 2: 465 err = -ENOSPC; 466 break; 467 default: 468 drop_nlink(dir); 469 clear_nlink(inode); 470 err = 0; 471 } 472 goto out; 473out1: 474 hpfs_brelse4(&qbh); 475out: 476 if (!err) 477 hpfs_update_directory_times(dir); 478 hpfs_unlock(dir->i_sb); 479 return err; 480} 481 482static int hpfs_symlink_read_folio(struct file *file, struct folio *folio) 483{ 484 struct page *page = &folio->page; 485 char *link = page_address(page); 486 struct inode *i = page->mapping->host; 487 struct fnode *fnode; 488 struct buffer_head *bh; 489 int err; 490 491 err = -EIO; 492 hpfs_lock(i->i_sb); 493 if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) 494 goto fail; 495 err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE); 496 brelse(bh); 497 if (err) 498 goto fail; 499 hpfs_unlock(i->i_sb); 500 SetPageUptodate(page); 501 unlock_page(page); 502 return 0; 503 504fail: 505 hpfs_unlock(i->i_sb); 506 SetPageError(page); 507 unlock_page(page); 508 return err; 509} 510 511const struct address_space_operations hpfs_symlink_aops = { 512 .read_folio = hpfs_symlink_read_folio 513}; 514 515static int hpfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, 516 struct dentry *old_dentry, struct inode *new_dir, 517 struct dentry *new_dentry, unsigned int flags) 518{ 519 const unsigned char *old_name = old_dentry->d_name.name; 520 unsigned old_len = old_dentry->d_name.len; 521 const unsigned char *new_name = new_dentry->d_name.name; 522 unsigned new_len = new_dentry->d_name.len; 523 struct inode *i = d_inode(old_dentry); 524 struct inode *new_inode = d_inode(new_dentry); 525 struct quad_buffer_head qbh, qbh1; 526 struct hpfs_dirent *dep, *nde; 527 struct hpfs_dirent de; 528 dnode_secno dno; 529 int r; 530 struct buffer_head *bh; 531 struct fnode *fnode; 532 int err; 533 534 if (flags & ~RENAME_NOREPLACE) 535 return -EINVAL; 536 537 if ((err = hpfs_chk_name(new_name, &new_len))) return err; 538 err = 0; 539 hpfs_adjust_length(old_name, &old_len); 540 541 hpfs_lock(i->i_sb); 542 /* order doesn't matter, due to VFS exclusion */ 543 544 /* Erm? Moving over the empty non-busy directory is perfectly legal */ 545 if (new_inode && S_ISDIR(new_inode->i_mode)) { 546 err = -EINVAL; 547 goto end1; 548 } 549 550 if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) { 551 hpfs_error(i->i_sb, "lookup succeeded but map dirent failed"); 552 err = -ENOENT; 553 goto end1; 554 } 555 copy_de(&de, dep); 556 de.hidden = new_name[0] == '.'; 557 558 if (new_inode) { 559 int r; 560 if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) { 561 if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, new_name, new_len, NULL, &qbh1))) { 562 clear_nlink(new_inode); 563 copy_de(nde, &de); 564 memcpy(nde->name, new_name, new_len); 565 hpfs_mark_4buffers_dirty(&qbh1); 566 hpfs_brelse4(&qbh1); 567 goto end; 568 } 569 hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent"); 570 err = -EFSERROR; 571 goto end1; 572 } 573 err = -ENOSPC; 574 goto end1; 575 } 576 577 if (new_dir == old_dir) hpfs_brelse4(&qbh); 578 579 if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de))) { 580 if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!"); 581 err = r == 1 ? -ENOSPC : -EFSERROR; 582 if (new_dir != old_dir) hpfs_brelse4(&qbh); 583 goto end1; 584 } 585 586 if (new_dir == old_dir) 587 if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, old_name, old_len, &dno, &qbh))) { 588 hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2"); 589 err = -ENOENT; 590 goto end1; 591 } 592 593 if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) { 594 hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent"); 595 err = r == 2 ? -ENOSPC : -EFSERROR; 596 goto end1; 597 } 598 599end: 600 hpfs_i(i)->i_parent_dir = new_dir->i_ino; 601 if (S_ISDIR(i->i_mode)) { 602 inc_nlink(new_dir); 603 drop_nlink(old_dir); 604 } 605 if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { 606 fnode->up = cpu_to_le32(new_dir->i_ino); 607 fnode->len = new_len; 608 memcpy(fnode->name, new_name, new_len>15?15:new_len); 609 if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len); 610 mark_buffer_dirty(bh); 611 brelse(bh); 612 } 613end1: 614 if (!err) { 615 hpfs_update_directory_times(old_dir); 616 hpfs_update_directory_times(new_dir); 617 } 618 hpfs_unlock(i->i_sb); 619 return err; 620} 621 622const struct inode_operations hpfs_dir_iops = 623{ 624 .create = hpfs_create, 625 .lookup = hpfs_lookup, 626 .unlink = hpfs_unlink, 627 .symlink = hpfs_symlink, 628 .mkdir = hpfs_mkdir, 629 .rmdir = hpfs_rmdir, 630 .mknod = hpfs_mknod, 631 .rename = hpfs_rename, 632 .setattr = hpfs_setattr, 633};