Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'fs_for_v6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull misc filesystem updates from Jan Kara:

- Rewrite kmap_local() handling in ext2

- Convert ext2 direct IO path to iomap (with some infrastructure tweaks
associated with that)

- Convert two boilerplate licenses in udf to SPDX identifiers

- Other small udf, ext2, and quota fixes and cleanups

* tag 'fs_for_v6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
udf: Fix uninitialized array access for some pathnames
ext2: Drop fragment support
quota: fix warning in dqgrab()
quota: Properly disable quotas when add_dquot_ref() fails
fs: udf: udftime: Replace LGPL boilerplate with SPDX identifier
fs: udf: Replace GPL 2.0 boilerplate license notice with SPDX identifier
fs: Drop wait_unfrozen wait queue
ext2_find_entry()/ext2_dotdot(): callers don't need page_addr anymore
ext2_{set_link,delete_entry}(): don't bother with page_addr
ext2_put_page(): accept any pointer within the page
ext2_get_page(): saner type
ext2: use offset_in_page() instead of open-coding it as subtraction
ext2_rename(): set_link and delete_entry may fail
ext2: Add direct-io trace points
ext2: Move direct-io to use iomap
ext2: Use generic_buffers_fsync() implementation
ext4: Use generic_buffers_fsync_noflush() implementation
fs/buffer.c: Add generic_buffers_fsync*() implementation
ext2/dax: Fix ext2_setsize when len is page aligned

+469 -291
+70
fs/buffer.c
··· 591 591 } 592 592 EXPORT_SYMBOL(sync_mapping_buffers); 593 593 594 + /** 595 + * generic_buffers_fsync_noflush - generic buffer fsync implementation 596 + * for simple filesystems with no inode lock 597 + * 598 + * @file: file to synchronize 599 + * @start: start offset in bytes 600 + * @end: end offset in bytes (inclusive) 601 + * @datasync: only synchronize essential metadata if true 602 + * 603 + * This is a generic implementation of the fsync method for simple 604 + * filesystems which track all non-inode metadata in the buffers list 605 + * hanging off the address_space structure. 606 + */ 607 + int generic_buffers_fsync_noflush(struct file *file, loff_t start, loff_t end, 608 + bool datasync) 609 + { 610 + struct inode *inode = file->f_mapping->host; 611 + int err; 612 + int ret; 613 + 614 + err = file_write_and_wait_range(file, start, end); 615 + if (err) 616 + return err; 617 + 618 + ret = sync_mapping_buffers(inode->i_mapping); 619 + if (!(inode->i_state & I_DIRTY_ALL)) 620 + goto out; 621 + if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) 622 + goto out; 623 + 624 + err = sync_inode_metadata(inode, 1); 625 + if (ret == 0) 626 + ret = err; 627 + 628 + out: 629 + /* check and advance again to catch errors after syncing out buffers */ 630 + err = file_check_and_advance_wb_err(file); 631 + if (ret == 0) 632 + ret = err; 633 + return ret; 634 + } 635 + EXPORT_SYMBOL(generic_buffers_fsync_noflush); 636 + 637 + /** 638 + * generic_buffers_fsync - generic buffer fsync implementation 639 + * for simple filesystems with no inode lock 640 + * 641 + * @file: file to synchronize 642 + * @start: start offset in bytes 643 + * @end: end offset in bytes (inclusive) 644 + * @datasync: only synchronize essential metadata if true 645 + * 646 + * This is a generic implementation of the fsync method for simple 647 + * filesystems which track all non-inode metadata in the buffers list 648 + * hanging off the address_space structure. This also makes sure that 649 + * a device cache flush operation is called at the end. 650 + */ 651 + int generic_buffers_fsync(struct file *file, loff_t start, loff_t end, 652 + bool datasync) 653 + { 654 + struct inode *inode = file->f_mapping->host; 655 + int ret; 656 + 657 + ret = generic_buffers_fsync_noflush(file, start, end, datasync); 658 + if (!ret) 659 + ret = blkdev_issue_flush(inode->i_sb->s_bdev); 660 + return ret; 661 + } 662 + EXPORT_SYMBOL(generic_buffers_fsync); 663 + 594 664 /* 595 665 * Called when we've recently written block `bblock', and it is known that 596 666 * `bblock' was for a buffer_boundary() buffer. This means that the block at
+4 -1
fs/ext2/Makefile
··· 6 6 obj-$(CONFIG_EXT2_FS) += ext2.o 7 7 8 8 ext2-y := balloc.o dir.o file.o ialloc.o inode.o \ 9 - ioctl.o namei.o super.o symlink.o 9 + ioctl.o namei.o super.o symlink.o trace.o 10 + 11 + # For tracepoints to include our trace.h from tracepoint infrastructure 12 + CFLAGS_trace.o := -I$(src) 10 13 11 14 ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o 12 15 ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o
+58 -78
fs/ext2/dir.c
··· 186 186 * NOTE: ext2_find_entry() and ext2_dotdot() act as a call to ext2_get_page() 187 187 * and should be treated as a call to ext2_get_page() for nesting purposes. 188 188 */ 189 - static struct page * ext2_get_page(struct inode *dir, unsigned long n, 190 - int quiet, void **page_addr) 189 + static void *ext2_get_page(struct inode *dir, unsigned long n, 190 + int quiet, struct page **page) 191 191 { 192 192 struct address_space *mapping = dir->i_mapping; 193 193 struct folio *folio = read_mapping_folio(mapping, n, NULL); 194 + void *page_addr; 194 195 195 196 if (IS_ERR(folio)) 196 - return &folio->page; 197 - *page_addr = kmap_local_folio(folio, n & (folio_nr_pages(folio) - 1)); 197 + return ERR_CAST(folio); 198 + page_addr = kmap_local_folio(folio, n & (folio_nr_pages(folio) - 1)); 198 199 if (unlikely(!folio_test_checked(folio))) { 199 - if (!ext2_check_page(&folio->page, quiet, *page_addr)) 200 + if (!ext2_check_page(&folio->page, quiet, page_addr)) 200 201 goto fail; 201 202 } 202 - return &folio->page; 203 + *page = &folio->page; 204 + return page_addr; 203 205 204 206 fail: 205 - ext2_put_page(&folio->page, *page_addr); 207 + ext2_put_page(&folio->page, page_addr); 206 208 return ERR_PTR(-EIO); 207 209 } 208 210 ··· 242 240 break; 243 241 p = ext2_next_entry(p); 244 242 } 245 - return (char *)p - base; 243 + return offset_in_page(p); 246 244 } 247 245 248 246 static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode) ··· 273 271 EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE); 274 272 275 273 for ( ; n < npages; n++, offset = 0) { 276 - char *kaddr, *limit; 277 274 ext2_dirent *de; 278 - struct page *page = ext2_get_page(inode, n, 0, (void **)&kaddr); 275 + struct page *page; 276 + char *kaddr = ext2_get_page(inode, n, 0, &page); 277 + char *limit; 279 278 280 - if (IS_ERR(page)) { 279 + if (IS_ERR(kaddr)) { 281 280 ext2_error(sb, __func__, 282 281 "bad page in #%lu", 283 282 inode->i_ino); 284 283 ctx->pos += PAGE_SIZE - offset; 285 - return PTR_ERR(page); 284 + return PTR_ERR(kaddr); 286 285 } 287 286 if (unlikely(need_revalidate)) { 288 287 if (offset) { ··· 299 296 if (de->rec_len == 0) { 300 297 ext2_error(sb, __func__, 301 298 "zero-length directory entry"); 302 - ext2_put_page(page, kaddr); 299 + ext2_put_page(page, de); 303 300 return -EIO; 304 301 } 305 302 if (de->inode) { ··· 311 308 if (!dir_emit(ctx, de->name, de->name_len, 312 309 le32_to_cpu(de->inode), 313 310 d_type)) { 314 - ext2_put_page(page, kaddr); 311 + ext2_put_page(page, de); 315 312 return 0; 316 313 } 317 314 } ··· 339 336 * should be treated as a call to ext2_get_page() for nesting purposes. 340 337 */ 341 338 struct ext2_dir_entry_2 *ext2_find_entry (struct inode *dir, 342 - const struct qstr *child, struct page **res_page, 343 - void **res_page_addr) 339 + const struct qstr *child, struct page **res_page) 344 340 { 345 341 const char *name = child->name; 346 342 int namelen = child->len; ··· 349 347 struct page *page = NULL; 350 348 struct ext2_inode_info *ei = EXT2_I(dir); 351 349 ext2_dirent * de; 352 - void *page_addr; 353 350 354 351 if (npages == 0) 355 352 goto out; 356 353 357 354 /* OFFSET_CACHE */ 358 355 *res_page = NULL; 359 - *res_page_addr = NULL; 360 356 361 357 start = ei->i_dir_start_lookup; 362 358 if (start >= npages) 363 359 start = 0; 364 360 n = start; 365 361 do { 366 - char *kaddr; 367 - page = ext2_get_page(dir, n, 0, &page_addr); 368 - if (IS_ERR(page)) 369 - return ERR_CAST(page); 362 + char *kaddr = ext2_get_page(dir, n, 0, &page); 363 + if (IS_ERR(kaddr)) 364 + return ERR_CAST(kaddr); 370 365 371 - kaddr = page_addr; 372 366 de = (ext2_dirent *) kaddr; 373 367 kaddr += ext2_last_byte(dir, n) - reclen; 374 368 while ((char *) de <= kaddr) { 375 369 if (de->rec_len == 0) { 376 370 ext2_error(dir->i_sb, __func__, 377 371 "zero-length directory entry"); 378 - ext2_put_page(page, page_addr); 372 + ext2_put_page(page, de); 379 373 goto out; 380 374 } 381 375 if (ext2_match(namelen, name, de)) 382 376 goto found; 383 377 de = ext2_next_entry(de); 384 378 } 385 - ext2_put_page(page, page_addr); 379 + ext2_put_page(page, kaddr); 386 380 387 381 if (++n >= npages) 388 382 n = 0; ··· 396 398 397 399 found: 398 400 *res_page = page; 399 - *res_page_addr = page_addr; 400 401 ei->i_dir_start_lookup = n; 401 402 return de; 402 403 } ··· 412 415 * ext2_find_entry() and ext2_dotdot() act as a call to ext2_get_page() and 413 416 * should be treated as a call to ext2_get_page() for nesting purposes. 414 417 */ 415 - struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p, 416 - void **pa) 418 + struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p) 417 419 { 418 - void *page_addr; 419 - struct page *page = ext2_get_page(dir, 0, 0, &page_addr); 420 - ext2_dirent *de = NULL; 420 + ext2_dirent *de = ext2_get_page(dir, 0, 0, p); 421 421 422 - if (!IS_ERR(page)) { 423 - de = ext2_next_entry((ext2_dirent *) page_addr); 424 - *p = page; 425 - *pa = page_addr; 426 - } 427 - return de; 422 + if (!IS_ERR(de)) 423 + return ext2_next_entry(de); 424 + return NULL; 428 425 } 429 426 430 427 int ext2_inode_by_name(struct inode *dir, const struct qstr *child, ino_t *ino) 431 428 { 432 429 struct ext2_dir_entry_2 *de; 433 430 struct page *page; 434 - void *page_addr; 435 431 436 - de = ext2_find_entry(dir, child, &page, &page_addr); 432 + de = ext2_find_entry(dir, child, &page); 437 433 if (IS_ERR(de)) 438 434 return PTR_ERR(de); 439 435 440 436 *ino = le32_to_cpu(de->inode); 441 - ext2_put_page(page, page_addr); 437 + ext2_put_page(page, de); 442 438 return 0; 443 439 } 444 440 ··· 452 462 } 453 463 454 464 int ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, 455 - struct page *page, void *page_addr, struct inode *inode, 456 - bool update_times) 465 + struct page *page, struct inode *inode, bool update_times) 457 466 { 458 - loff_t pos = page_offset(page) + 459 - (char *) de - (char *) page_addr; 467 + loff_t pos = page_offset(page) + offset_in_page(de); 460 468 unsigned len = ext2_rec_len_from_disk(de->rec_len); 461 469 int err; 462 470 ··· 486 498 unsigned reclen = EXT2_DIR_REC_LEN(namelen); 487 499 unsigned short rec_len, name_len; 488 500 struct page *page = NULL; 489 - void *page_addr = NULL; 490 501 ext2_dirent * de; 491 502 unsigned long npages = dir_pages(dir); 492 503 unsigned long n; ··· 498 511 * to protect that region. 499 512 */ 500 513 for (n = 0; n <= npages; n++) { 501 - char *kaddr; 514 + char *kaddr = ext2_get_page(dir, n, 0, &page); 502 515 char *dir_end; 503 516 504 - page = ext2_get_page(dir, n, 0, &page_addr); 505 - err = PTR_ERR(page); 506 - if (IS_ERR(page)) 507 - goto out; 517 + if (IS_ERR(kaddr)) 518 + return PTR_ERR(kaddr); 508 519 lock_page(page); 509 - kaddr = page_addr; 510 520 dir_end = kaddr + ext2_last_byte(dir, n); 511 521 de = (ext2_dirent *)kaddr; 512 522 kaddr += PAGE_SIZE - reclen; ··· 534 550 de = (ext2_dirent *) ((char *) de + rec_len); 535 551 } 536 552 unlock_page(page); 537 - ext2_put_page(page, page_addr); 553 + ext2_put_page(page, kaddr); 538 554 } 539 555 BUG(); 540 556 return -EINVAL; 541 557 542 558 got_it: 543 - pos = page_offset(page) + 544 - (char *)de - (char *)page_addr; 559 + pos = page_offset(page) + offset_in_page(de); 545 560 err = ext2_prepare_chunk(page, pos, rec_len); 546 561 if (err) 547 562 goto out_unlock; ··· 561 578 err = ext2_handle_dirsync(dir); 562 579 /* OFFSET_CACHE */ 563 580 out_put: 564 - ext2_put_page(page, page_addr); 565 - out: 581 + ext2_put_page(page, de); 566 582 return err; 567 583 out_unlock: 568 584 unlock_page(page); ··· 572 590 * ext2_delete_entry deletes a directory entry by merging it with the 573 591 * previous entry. Page is up-to-date. 574 592 */ 575 - int ext2_delete_entry (struct ext2_dir_entry_2 *dir, struct page *page, 576 - char *kaddr) 593 + int ext2_delete_entry(struct ext2_dir_entry_2 *dir, struct page *page) 577 594 { 578 595 struct inode *inode = page->mapping->host; 579 - unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); 580 - unsigned to = ((char *)dir - kaddr) + 596 + char *kaddr = (char *)((unsigned long)dir & PAGE_MASK); 597 + unsigned from = offset_in_page(dir) & ~(ext2_chunk_size(inode)-1); 598 + unsigned to = offset_in_page(dir) + 581 599 ext2_rec_len_from_disk(dir->rec_len); 582 600 loff_t pos; 583 - ext2_dirent * pde = NULL; 584 - ext2_dirent * de = (ext2_dirent *) (kaddr + from); 601 + ext2_dirent *pde = NULL; 602 + ext2_dirent *de = (ext2_dirent *)(kaddr + from); 585 603 int err; 586 604 587 605 while ((char*)de < (char*)dir) { 588 606 if (de->rec_len == 0) { 589 607 ext2_error(inode->i_sb, __func__, 590 608 "zero-length directory entry"); 591 - err = -EIO; 592 - goto out; 609 + return -EIO; 593 610 } 594 611 pde = de; 595 612 de = ext2_next_entry(de); 596 613 } 597 614 if (pde) 598 - from = (char *)pde - kaddr; 615 + from = offset_in_page(pde); 599 616 pos = page_offset(page) + from; 600 617 lock_page(page); 601 618 err = ext2_prepare_chunk(page, pos, to - from); 602 - BUG_ON(err); 619 + if (err) { 620 + unlock_page(page); 621 + return err; 622 + } 603 623 if (pde) 604 624 pde->rec_len = ext2_rec_len_to_disk(to - from); 605 625 dir->inode = 0; ··· 609 625 inode->i_ctime = inode->i_mtime = current_time(inode); 610 626 EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL; 611 627 mark_inode_dirty(inode); 612 - err = ext2_handle_dirsync(inode); 613 - out: 614 - return err; 628 + return ext2_handle_dirsync(inode); 615 629 } 616 630 617 631 /* ··· 659 677 */ 660 678 int ext2_empty_dir (struct inode * inode) 661 679 { 662 - void *page_addr = NULL; 663 - struct page *page = NULL; 680 + struct page *page; 681 + char *kaddr; 664 682 unsigned long i, npages = dir_pages(inode); 665 683 666 684 for (i = 0; i < npages; i++) { 667 - char *kaddr; 668 - ext2_dirent * de; 669 - page = ext2_get_page(inode, i, 0, &page_addr); 685 + ext2_dirent *de; 670 686 671 - if (IS_ERR(page)) 687 + kaddr = ext2_get_page(inode, i, 0, &page); 688 + if (IS_ERR(kaddr)) 672 689 return 0; 673 690 674 - kaddr = page_addr; 675 691 de = (ext2_dirent *)kaddr; 676 692 kaddr += ext2_last_byte(inode, i) - EXT2_DIR_REC_LEN(1); 677 693 ··· 695 715 } 696 716 de = ext2_next_entry(de); 697 717 } 698 - ext2_put_page(page, page_addr); 718 + ext2_put_page(page, kaddr); 699 719 } 700 720 return 1; 701 721 702 722 not_empty: 703 - ext2_put_page(page, page_addr); 723 + ext2_put_page(page, kaddr); 704 724 return 0; 705 725 } 706 726
+5 -18
fs/ext2/ext2.h
··· 70 70 * second extended-fs super-block data in memory 71 71 */ 72 72 struct ext2_sb_info { 73 - unsigned long s_frag_size; /* Size of a fragment in bytes */ 74 - unsigned long s_frags_per_block;/* Number of fragments per block */ 75 73 unsigned long s_inodes_per_block;/* Number of inodes per block */ 76 - unsigned long s_frags_per_group;/* Number of fragments in a group */ 77 74 unsigned long s_blocks_per_group;/* Number of blocks in a group */ 78 75 unsigned long s_inodes_per_group;/* Number of inodes in a group */ 79 76 unsigned long s_itb_per_group; /* Number of inode table blocks per group */ ··· 184 187 #define EXT2_ADDR_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_addr_per_block_bits) 185 188 #define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size) 186 189 #define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino) 187 - 188 - /* 189 - * Macro-instructions used to manage fragments 190 - */ 191 - #define EXT2_MIN_FRAG_SIZE 1024 192 - #define EXT2_MAX_FRAG_SIZE 4096 193 - #define EXT2_MIN_FRAG_LOG_SIZE 10 194 - #define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size) 195 - #define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block) 196 190 197 191 /* 198 192 * Structure of a blocks group descriptor ··· 718 730 const struct qstr *child, ino_t *ino); 719 731 extern int ext2_make_empty(struct inode *, struct inode *); 720 732 extern struct ext2_dir_entry_2 *ext2_find_entry(struct inode *, const struct qstr *, 721 - struct page **, void **res_page_addr); 722 - extern int ext2_delete_entry(struct ext2_dir_entry_2 *dir, struct page *page, 723 - char *kaddr); 733 + struct page **); 734 + extern int ext2_delete_entry(struct ext2_dir_entry_2 *dir, struct page *page); 724 735 extern int ext2_empty_dir (struct inode *); 725 - extern struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p, void **pa); 736 + extern struct ext2_dir_entry_2 *ext2_dotdot(struct inode *dir, struct page **p); 726 737 int ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, 727 - struct page *page, void *page_addr, struct inode *inode, 728 - bool update_times); 738 + struct page *page, struct inode *inode, bool update_times); 729 739 static inline void ext2_put_page(struct page *page, void *page_addr) 730 740 { 731 741 kunmap_local(page_addr); ··· 740 754 extern struct inode *ext2_iget (struct super_block *, unsigned long); 741 755 extern int ext2_write_inode (struct inode *, struct writeback_control *); 742 756 extern void ext2_evict_inode(struct inode *); 757 + void ext2_write_failed(struct address_space *mapping, loff_t to); 743 758 extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); 744 759 extern int ext2_setattr (struct mnt_idmap *, struct dentry *, struct iattr *); 745 760 extern int ext2_getattr (struct mnt_idmap *, const struct path *,
+125 -1
fs/ext2/file.c
··· 25 25 #include <linux/quotaops.h> 26 26 #include <linux/iomap.h> 27 27 #include <linux/uio.h> 28 + #include <linux/buffer_head.h> 28 29 #include "ext2.h" 29 30 #include "xattr.h" 30 31 #include "acl.h" 32 + #include "trace.h" 31 33 32 34 #ifdef CONFIG_FS_DAX 33 35 static ssize_t ext2_dax_read_iter(struct kiocb *iocb, struct iov_iter *to) ··· 155 153 int ret; 156 154 struct super_block *sb = file->f_mapping->host->i_sb; 157 155 158 - ret = generic_file_fsync(file, start, end, datasync); 156 + ret = generic_buffers_fsync(file, start, end, datasync); 159 157 if (ret == -EIO) 160 158 /* We don't really know where the IO error happened... */ 161 159 ext2_error(sb, __func__, 162 160 "detected IO error when writing metadata buffers"); 161 + return ret; 162 + } 163 + 164 + static ssize_t ext2_dio_read_iter(struct kiocb *iocb, struct iov_iter *to) 165 + { 166 + struct file *file = iocb->ki_filp; 167 + struct inode *inode = file->f_mapping->host; 168 + ssize_t ret; 169 + 170 + trace_ext2_dio_read_begin(iocb, to, 0); 171 + inode_lock_shared(inode); 172 + ret = iomap_dio_rw(iocb, to, &ext2_iomap_ops, NULL, 0, NULL, 0); 173 + inode_unlock_shared(inode); 174 + trace_ext2_dio_read_end(iocb, to, ret); 175 + 176 + return ret; 177 + } 178 + 179 + static int ext2_dio_write_end_io(struct kiocb *iocb, ssize_t size, 180 + int error, unsigned int flags) 181 + { 182 + loff_t pos = iocb->ki_pos; 183 + struct inode *inode = file_inode(iocb->ki_filp); 184 + 185 + if (error) 186 + goto out; 187 + 188 + /* 189 + * If we are extending the file, we have to update i_size here before 190 + * page cache gets invalidated in iomap_dio_rw(). This prevents racing 191 + * buffered reads from zeroing out too much from page cache pages. 192 + * Note that all extending writes always happens synchronously with 193 + * inode lock held by ext2_dio_write_iter(). So it is safe to update 194 + * inode size here for extending file writes. 195 + */ 196 + pos += size; 197 + if (pos > i_size_read(inode)) { 198 + i_size_write(inode, pos); 199 + mark_inode_dirty(inode); 200 + } 201 + out: 202 + trace_ext2_dio_write_endio(iocb, size, error); 203 + return error; 204 + } 205 + 206 + static const struct iomap_dio_ops ext2_dio_write_ops = { 207 + .end_io = ext2_dio_write_end_io, 208 + }; 209 + 210 + static ssize_t ext2_dio_write_iter(struct kiocb *iocb, struct iov_iter *from) 211 + { 212 + struct file *file = iocb->ki_filp; 213 + struct inode *inode = file->f_mapping->host; 214 + ssize_t ret; 215 + unsigned int flags = 0; 216 + unsigned long blocksize = inode->i_sb->s_blocksize; 217 + loff_t offset = iocb->ki_pos; 218 + loff_t count = iov_iter_count(from); 219 + ssize_t status = 0; 220 + 221 + trace_ext2_dio_write_begin(iocb, from, 0); 222 + inode_lock(inode); 223 + ret = generic_write_checks(iocb, from); 224 + if (ret <= 0) 225 + goto out_unlock; 226 + 227 + ret = kiocb_modified(iocb); 228 + if (ret) 229 + goto out_unlock; 230 + 231 + /* use IOMAP_DIO_FORCE_WAIT for unaligned or extending writes */ 232 + if (iocb->ki_pos + iov_iter_count(from) > i_size_read(inode) || 233 + (!IS_ALIGNED(iocb->ki_pos | iov_iter_alignment(from), blocksize))) 234 + flags |= IOMAP_DIO_FORCE_WAIT; 235 + 236 + ret = iomap_dio_rw(iocb, from, &ext2_iomap_ops, &ext2_dio_write_ops, 237 + flags, NULL, 0); 238 + 239 + /* ENOTBLK is magic return value for fallback to buffered-io */ 240 + if (ret == -ENOTBLK) 241 + ret = 0; 242 + 243 + if (ret < 0 && ret != -EIOCBQUEUED) 244 + ext2_write_failed(inode->i_mapping, offset + count); 245 + 246 + /* handle case for partial write and for fallback to buffered write */ 247 + if (ret >= 0 && iov_iter_count(from)) { 248 + loff_t pos, endbyte; 249 + int ret2; 250 + 251 + iocb->ki_flags &= ~IOCB_DIRECT; 252 + pos = iocb->ki_pos; 253 + status = generic_perform_write(iocb, from); 254 + if (unlikely(status < 0)) { 255 + ret = status; 256 + goto out_unlock; 257 + } 258 + 259 + iocb->ki_pos += status; 260 + ret += status; 261 + endbyte = pos + status - 1; 262 + ret2 = filemap_write_and_wait_range(inode->i_mapping, pos, 263 + endbyte); 264 + if (!ret2) 265 + invalidate_mapping_pages(inode->i_mapping, 266 + pos >> PAGE_SHIFT, 267 + endbyte >> PAGE_SHIFT); 268 + if (ret > 0) 269 + generic_write_sync(iocb, ret); 270 + } 271 + 272 + out_unlock: 273 + inode_unlock(inode); 274 + if (status) 275 + trace_ext2_dio_write_buff_end(iocb, from, status); 276 + trace_ext2_dio_write_end(iocb, from, ret); 163 277 return ret; 164 278 } 165 279 ··· 285 167 if (IS_DAX(iocb->ki_filp->f_mapping->host)) 286 168 return ext2_dax_read_iter(iocb, to); 287 169 #endif 170 + if (iocb->ki_flags & IOCB_DIRECT) 171 + return ext2_dio_read_iter(iocb, to); 172 + 288 173 return generic_file_read_iter(iocb, to); 289 174 } 290 175 ··· 297 176 if (IS_DAX(iocb->ki_filp->f_mapping->host)) 298 177 return ext2_dax_write_iter(iocb, from); 299 178 #endif 179 + if (iocb->ki_flags & IOCB_DIRECT) 180 + return ext2_dio_write_iter(iocb, from); 181 + 300 182 return generic_file_write_iter(iocb, from); 301 183 } 302 184
+36 -22
fs/ext2/inode.c
··· 56 56 57 57 static void ext2_truncate_blocks(struct inode *inode, loff_t offset); 58 58 59 - static void ext2_write_failed(struct address_space *mapping, loff_t to) 59 + void ext2_write_failed(struct address_space *mapping, loff_t to) 60 60 { 61 61 struct inode *inode = mapping->host; 62 62 ··· 809 809 bool new = false, boundary = false; 810 810 u32 bno; 811 811 int ret; 812 + bool create = flags & IOMAP_WRITE; 813 + 814 + /* 815 + * For writes that could fill holes inside i_size on a 816 + * DIO_SKIP_HOLES filesystem we forbid block creations: only 817 + * overwrites are permitted. 818 + */ 819 + if ((flags & IOMAP_DIRECT) && 820 + (first_block << blkbits) < i_size_read(inode)) 821 + create = 0; 822 + 823 + /* 824 + * Writes that span EOF might trigger an IO size update on completion, 825 + * so consider them to be dirty for the purposes of O_DSYNC even if 826 + * there is no other metadata changes pending or have been made here. 827 + */ 828 + if ((flags & IOMAP_WRITE) && offset + length > i_size_read(inode)) 829 + iomap->flags |= IOMAP_F_DIRTY; 812 830 813 831 ret = ext2_get_blocks(inode, first_block, max_blocks, 814 - &bno, &new, &boundary, flags & IOMAP_WRITE); 832 + &bno, &new, &boundary, create); 815 833 if (ret < 0) 816 834 return ret; 817 835 ··· 841 823 iomap->bdev = inode->i_sb->s_bdev; 842 824 843 825 if (ret == 0) { 826 + /* 827 + * Switch to buffered-io for writing to holes in a non-extent 828 + * based filesystem to avoid stale data exposure problem. 829 + */ 830 + if (!create && (flags & IOMAP_WRITE) && (flags & IOMAP_DIRECT)) 831 + return -ENOTBLK; 844 832 iomap->type = IOMAP_HOLE; 845 833 iomap->addr = IOMAP_NULL_ADDR; 846 834 iomap->length = 1 << blkbits; ··· 868 844 ext2_iomap_end(struct inode *inode, loff_t offset, loff_t length, 869 845 ssize_t written, unsigned flags, struct iomap *iomap) 870 846 { 847 + /* 848 + * Switch to buffered-io in case of any error. 849 + * Blocks allocated can be used by the buffered-io path. 850 + */ 851 + if ((flags & IOMAP_DIRECT) && (flags & IOMAP_WRITE) && written == 0) 852 + return -ENOTBLK; 853 + 871 854 if (iomap->type == IOMAP_MAPPED && 872 855 written < length && 873 856 (flags & IOMAP_WRITE)) ··· 939 908 return generic_block_bmap(mapping,block,ext2_get_block); 940 909 } 941 910 942 - static ssize_t 943 - ext2_direct_IO(struct kiocb *iocb, struct iov_iter *iter) 944 - { 945 - struct file *file = iocb->ki_filp; 946 - struct address_space *mapping = file->f_mapping; 947 - struct inode *inode = mapping->host; 948 - size_t count = iov_iter_count(iter); 949 - loff_t offset = iocb->ki_pos; 950 - ssize_t ret; 951 - 952 - ret = blockdev_direct_IO(iocb, inode, iter, ext2_get_block); 953 - if (ret < 0 && iov_iter_rw(iter) == WRITE) 954 - ext2_write_failed(mapping, offset + count); 955 - return ret; 956 - } 957 - 958 911 static int 959 912 ext2_writepages(struct address_space *mapping, struct writeback_control *wbc) 960 913 { ··· 961 946 .write_begin = ext2_write_begin, 962 947 .write_end = ext2_write_end, 963 948 .bmap = ext2_bmap, 964 - .direct_IO = ext2_direct_IO, 949 + .direct_IO = noop_direct_IO, 965 950 .writepages = ext2_writepages, 966 951 .migrate_folio = buffer_migrate_folio, 967 952 .is_partially_uptodate = block_is_partially_uptodate, ··· 1274 1259 inode_dio_wait(inode); 1275 1260 1276 1261 if (IS_DAX(inode)) 1277 - error = dax_zero_range(inode, newsize, 1278 - PAGE_ALIGN(newsize) - newsize, NULL, 1279 - &ext2_iomap_ops); 1262 + error = dax_truncate_page(inode, newsize, NULL, 1263 + &ext2_iomap_ops); 1280 1264 else 1281 1265 error = block_truncate_page(inode->i_mapping, 1282 1266 newsize, ext2_get_block);
+24 -39
fs/ext2/namei.c
··· 269 269 goto out; 270 270 } 271 271 272 - static int ext2_unlink(struct inode * dir, struct dentry *dentry) 272 + static int ext2_unlink(struct inode *dir, struct dentry *dentry) 273 273 { 274 - struct inode * inode = d_inode(dentry); 275 - struct ext2_dir_entry_2 * de; 276 - struct page * page; 277 - void *page_addr; 274 + struct inode *inode = d_inode(dentry); 275 + struct ext2_dir_entry_2 *de; 276 + struct page *page; 278 277 int err; 279 278 280 279 err = dquot_initialize(dir); 281 280 if (err) 282 281 goto out; 283 282 284 - de = ext2_find_entry(dir, &dentry->d_name, &page, &page_addr); 283 + de = ext2_find_entry(dir, &dentry->d_name, &page); 285 284 if (IS_ERR(de)) { 286 285 err = PTR_ERR(de); 287 286 goto out; 288 287 } 289 288 290 - err = ext2_delete_entry (de, page, page_addr); 291 - ext2_put_page(page, page_addr); 289 + err = ext2_delete_entry(de, page); 290 + ext2_put_page(page, de); 292 291 if (err) 293 292 goto out; 294 293 ··· 322 323 struct inode * old_inode = d_inode(old_dentry); 323 324 struct inode * new_inode = d_inode(new_dentry); 324 325 struct page * dir_page = NULL; 325 - void *dir_page_addr; 326 326 struct ext2_dir_entry_2 * dir_de = NULL; 327 327 struct page * old_page; 328 - void *old_page_addr; 329 328 struct ext2_dir_entry_2 * old_de; 330 329 int err; 331 330 ··· 332 335 333 336 err = dquot_initialize(old_dir); 334 337 if (err) 335 - goto out; 338 + return err; 336 339 337 340 err = dquot_initialize(new_dir); 338 341 if (err) 339 - goto out; 342 + return err; 340 343 341 - old_de = ext2_find_entry(old_dir, &old_dentry->d_name, &old_page, 342 - &old_page_addr); 343 - if (IS_ERR(old_de)) { 344 - err = PTR_ERR(old_de); 345 - goto out; 346 - } 344 + old_de = ext2_find_entry(old_dir, &old_dentry->d_name, &old_page); 345 + if (IS_ERR(old_de)) 346 + return PTR_ERR(old_de); 347 347 348 348 if (S_ISDIR(old_inode->i_mode)) { 349 349 err = -EIO; 350 - dir_de = ext2_dotdot(old_inode, &dir_page, &dir_page_addr); 350 + dir_de = ext2_dotdot(old_inode, &dir_page); 351 351 if (!dir_de) 352 352 goto out_old; 353 353 } 354 354 355 355 if (new_inode) { 356 - void *page_addr; 357 356 struct page *new_page; 358 357 struct ext2_dir_entry_2 *new_de; 359 358 ··· 358 365 goto out_dir; 359 366 360 367 new_de = ext2_find_entry(new_dir, &new_dentry->d_name, 361 - &new_page, &page_addr); 368 + &new_page); 362 369 if (IS_ERR(new_de)) { 363 370 err = PTR_ERR(new_de); 364 371 goto out_dir; 365 372 } 366 - err = ext2_set_link(new_dir, new_de, new_page, page_addr, 367 - old_inode, true); 368 - ext2_put_page(new_page, page_addr); 373 + err = ext2_set_link(new_dir, new_de, new_page, old_inode, true); 374 + ext2_put_page(new_page, new_de); 369 375 if (err) 370 376 goto out_dir; 371 377 new_inode->i_ctime = current_time(new_inode); ··· 386 394 old_inode->i_ctime = current_time(old_inode); 387 395 mark_inode_dirty(old_inode); 388 396 389 - ext2_delete_entry(old_de, old_page, old_page_addr); 390 - 391 - if (dir_de) { 392 - if (old_dir != new_dir) { 397 + err = ext2_delete_entry(old_de, old_page); 398 + if (!err && dir_de) { 399 + if (old_dir != new_dir) 393 400 err = ext2_set_link(old_inode, dir_de, dir_page, 394 - dir_page_addr, new_dir, false); 401 + new_dir, false); 395 402 396 - } 397 - ext2_put_page(dir_page, dir_page_addr); 398 403 inode_dec_link_count(old_dir); 399 404 } 400 - 401 - out_old: 402 - ext2_put_page(old_page, old_page_addr); 403 - out: 404 - return err; 405 - 406 405 out_dir: 407 406 if (dir_de) 408 - ext2_put_page(dir_page, dir_page_addr); 409 - goto out_old; 407 + ext2_put_page(dir_page, dir_de); 408 + out_old: 409 + ext2_put_page(old_page, old_de); 410 + return err; 410 411 } 411 412 412 413 const struct inode_operations ext2_dir_inode_operations = {
+4 -19
fs/ext2/super.c
··· 668 668 es->s_max_mnt_count = cpu_to_le16(EXT2_DFL_MAX_MNT_COUNT); 669 669 le16_add_cpu(&es->s_mnt_count, 1); 670 670 if (test_opt (sb, DEBUG)) 671 - ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, fs=%lu, gc=%lu, " 671 + ext2_msg(sb, KERN_INFO, "%s, %s, bs=%lu, gc=%lu, " 672 672 "bpg=%lu, ipg=%lu, mo=%04lx]", 673 673 EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, 674 - sbi->s_frag_size, 675 674 sbi->s_groups_count, 676 675 EXT2_BLOCKS_PER_GROUP(sb), 677 676 EXT2_INODES_PER_GROUP(sb), ··· 1011 1012 } 1012 1013 } 1013 1014 1014 - sbi->s_frag_size = EXT2_MIN_FRAG_SIZE << 1015 - le32_to_cpu(es->s_log_frag_size); 1016 - if (sbi->s_frag_size == 0) 1017 - goto cantfind_ext2; 1018 - sbi->s_frags_per_block = sb->s_blocksize / sbi->s_frag_size; 1019 - 1020 1015 sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); 1021 - sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); 1022 1016 sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); 1023 1017 1024 1018 sbi->s_inodes_per_block = sb->s_blocksize / EXT2_INODE_SIZE(sb); ··· 1037 1045 goto failed_mount; 1038 1046 } 1039 1047 1040 - if (sb->s_blocksize != sbi->s_frag_size) { 1048 + if (es->s_log_frag_size != es->s_log_block_size) { 1041 1049 ext2_msg(sb, KERN_ERR, 1042 - "error: fragsize %lu != blocksize %lu" 1043 - "(not supported yet)", 1044 - sbi->s_frag_size, sb->s_blocksize); 1050 + "error: fragsize log %u != blocksize log %u", 1051 + le32_to_cpu(es->s_log_frag_size), sb->s_blocksize_bits); 1045 1052 goto failed_mount; 1046 1053 } 1047 1054 ··· 1055 1064 ext2_msg(sb, KERN_ERR, 1056 1065 "error: #blocks per group smaller than metadata size: %lu <= %lu", 1057 1066 sbi->s_blocks_per_group, sbi->s_inodes_per_group + 3); 1058 - goto failed_mount; 1059 - } 1060 - if (sbi->s_frags_per_group > sb->s_blocksize * 8) { 1061 - ext2_msg(sb, KERN_ERR, 1062 - "error: #fragments per group too big: %lu", 1063 - sbi->s_frags_per_group); 1064 1067 goto failed_mount; 1065 1068 } 1066 1069 if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
+6
fs/ext2/trace.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include "ext2.h" 3 + #include <linux/uio.h> 4 + 5 + #define CREATE_TRACE_POINTS 6 + #include "trace.h"
+94
fs/ext2/trace.h
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #undef TRACE_SYSTEM 4 + #define TRACE_SYSTEM ext2 5 + 6 + #if !defined(_EXT2_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) 7 + #define _EXT2_TRACE_H 8 + 9 + #include <linux/tracepoint.h> 10 + 11 + DECLARE_EVENT_CLASS(ext2_dio_class, 12 + TP_PROTO(struct kiocb *iocb, struct iov_iter *iter, ssize_t ret), 13 + TP_ARGS(iocb, iter, ret), 14 + TP_STRUCT__entry( 15 + __field(dev_t, dev) 16 + __field(ino_t, ino) 17 + __field(loff_t, isize) 18 + __field(loff_t, pos) 19 + __field(size_t, count) 20 + __field(int, ki_flags) 21 + __field(bool, aio) 22 + __field(ssize_t, ret) 23 + ), 24 + TP_fast_assign( 25 + __entry->dev = file_inode(iocb->ki_filp)->i_sb->s_dev; 26 + __entry->ino = file_inode(iocb->ki_filp)->i_ino; 27 + __entry->isize = file_inode(iocb->ki_filp)->i_size; 28 + __entry->pos = iocb->ki_pos; 29 + __entry->count = iov_iter_count(iter); 30 + __entry->ki_flags = iocb->ki_flags; 31 + __entry->aio = !is_sync_kiocb(iocb); 32 + __entry->ret = ret; 33 + ), 34 + TP_printk("dev %d:%d ino 0x%lx isize 0x%llx pos 0x%llx len %zu flags %s aio %d ret %zd", 35 + MAJOR(__entry->dev), MINOR(__entry->dev), 36 + __entry->ino, 37 + __entry->isize, 38 + __entry->pos, 39 + __entry->count, 40 + __print_flags(__entry->ki_flags, "|", TRACE_IOCB_STRINGS), 41 + __entry->aio, 42 + __entry->ret) 43 + ); 44 + 45 + #define DEFINE_DIO_RW_EVENT(name) \ 46 + DEFINE_EVENT(ext2_dio_class, name, \ 47 + TP_PROTO(struct kiocb *iocb, struct iov_iter *iter, ssize_t ret), \ 48 + TP_ARGS(iocb, iter, ret)) 49 + DEFINE_DIO_RW_EVENT(ext2_dio_write_begin); 50 + DEFINE_DIO_RW_EVENT(ext2_dio_write_end); 51 + DEFINE_DIO_RW_EVENT(ext2_dio_write_buff_end); 52 + DEFINE_DIO_RW_EVENT(ext2_dio_read_begin); 53 + DEFINE_DIO_RW_EVENT(ext2_dio_read_end); 54 + 55 + TRACE_EVENT(ext2_dio_write_endio, 56 + TP_PROTO(struct kiocb *iocb, ssize_t size, int ret), 57 + TP_ARGS(iocb, size, ret), 58 + TP_STRUCT__entry( 59 + __field(dev_t, dev) 60 + __field(ino_t, ino) 61 + __field(loff_t, isize) 62 + __field(loff_t, pos) 63 + __field(ssize_t, size) 64 + __field(int, ki_flags) 65 + __field(bool, aio) 66 + __field(int, ret) 67 + ), 68 + TP_fast_assign( 69 + __entry->dev = file_inode(iocb->ki_filp)->i_sb->s_dev; 70 + __entry->ino = file_inode(iocb->ki_filp)->i_ino; 71 + __entry->isize = file_inode(iocb->ki_filp)->i_size; 72 + __entry->pos = iocb->ki_pos; 73 + __entry->size = size; 74 + __entry->ki_flags = iocb->ki_flags; 75 + __entry->aio = !is_sync_kiocb(iocb); 76 + __entry->ret = ret; 77 + ), 78 + TP_printk("dev %d:%d ino 0x%lx isize 0x%llx pos 0x%llx len %zd flags %s aio %d ret %d", 79 + MAJOR(__entry->dev), MINOR(__entry->dev), 80 + __entry->ino, 81 + __entry->isize, 82 + __entry->pos, 83 + __entry->size, 84 + __print_flags(__entry->ki_flags, "|", TRACE_IOCB_STRINGS), 85 + __entry->aio, 86 + __entry->ret) 87 + ); 88 + 89 + #endif /* _EXT2_TRACE_H */ 90 + 91 + #undef TRACE_INCLUDE_PATH 92 + #define TRACE_INCLUDE_PATH . 93 + #define TRACE_INCLUDE_FILE trace 94 + #include <trace/define_trace.h>
+16 -17
fs/ext4/fsync.c
··· 28 28 #include <linux/sched.h> 29 29 #include <linux/writeback.h> 30 30 #include <linux/blkdev.h> 31 + #include <linux/buffer_head.h> 31 32 32 33 #include "ext4.h" 33 34 #include "ext4_jbd2.h" ··· 79 78 return ret; 80 79 } 81 80 82 - static int ext4_fsync_nojournal(struct inode *inode, bool datasync, 83 - bool *needs_barrier) 81 + static int ext4_fsync_nojournal(struct file *file, loff_t start, loff_t end, 82 + int datasync, bool *needs_barrier) 84 83 { 85 - int ret, err; 84 + struct inode *inode = file->f_inode; 85 + int ret; 86 86 87 - ret = sync_mapping_buffers(inode->i_mapping); 88 - if (!(inode->i_state & I_DIRTY_ALL)) 89 - return ret; 90 - if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) 91 - return ret; 92 - 93 - err = sync_inode_metadata(inode, 1); 94 - if (!ret) 95 - ret = err; 96 - 87 + ret = generic_buffers_fsync_noflush(file, start, end, datasync); 97 88 if (!ret) 98 89 ret = ext4_sync_parent(inode); 99 90 if (test_opt(inode->i_sb, BARRIER)) ··· 148 155 goto out; 149 156 } 150 157 158 + if (!sbi->s_journal) { 159 + ret = ext4_fsync_nojournal(file, start, end, datasync, 160 + &needs_barrier); 161 + if (needs_barrier) 162 + goto issue_flush; 163 + goto out; 164 + } 165 + 151 166 ret = file_write_and_wait_range(file, start, end); 152 167 if (ret) 153 168 goto out; ··· 165 164 * Metadata is in the journal, we wait for proper transaction to 166 165 * commit here. 167 166 */ 168 - if (!sbi->s_journal) 169 - ret = ext4_fsync_nojournal(inode, datasync, &needs_barrier); 170 - else 171 - ret = ext4_fsync_journal(inode, datasync, &needs_barrier); 167 + ret = ext4_fsync_journal(inode, datasync, &needs_barrier); 172 168 169 + issue_flush: 173 170 if (needs_barrier) { 174 171 err = blkdev_issue_flush(inode->i_sb->s_bdev); 175 172 if (!ret)
+3 -2
fs/quota/dquot.c
··· 555 555 continue; 556 556 /* Wait for dquot users */ 557 557 if (atomic_read(&dquot->dq_count)) { 558 - dqgrab(dquot); 558 + atomic_inc(&dquot->dq_count); 559 559 spin_unlock(&dq_list_lock); 560 560 /* 561 561 * Once dqput() wakes us up, we know it's time to free ··· 2420 2420 2421 2421 error = add_dquot_ref(sb, type); 2422 2422 if (error) 2423 - dquot_disable(sb, type, flags); 2423 + dquot_disable(sb, type, 2424 + DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); 2424 2425 2425 2426 return error; 2426 2427 out_fmt:
+3 -2
fs/quota/quota.c
··· 895 895 up_write(&sb->s_umount); 896 896 else 897 897 up_read(&sb->s_umount); 898 - wait_event(sb->s_writers.wait_unfrozen, 899 - sb->s_writers.frozen == SB_UNFROZEN); 898 + /* Wait for sb to unfreeze */ 899 + sb_start_write(sb); 900 + sb_end_write(sb); 900 901 put_super(sb); 901 902 goto retry; 902 903 }
-4
fs/super.c
··· 236 236 &type->s_writers_key[i])) 237 237 goto fail; 238 238 } 239 - init_waitqueue_head(&s->s_writers.wait_unfrozen); 240 239 s->s_bdi = &noop_backing_dev_info; 241 240 s->s_flags = flags; 242 241 if (s->s_user_ns != &init_user_ns) ··· 1715 1716 if (ret) { 1716 1717 sb->s_writers.frozen = SB_UNFROZEN; 1717 1718 sb_freeze_unlock(sb, SB_FREEZE_PAGEFAULT); 1718 - wake_up(&sb->s_writers.wait_unfrozen); 1719 1719 deactivate_locked_super(sb); 1720 1720 return ret; 1721 1721 } ··· 1730 1732 "VFS:Filesystem freeze failed\n"); 1731 1733 sb->s_writers.frozen = SB_UNFROZEN; 1732 1734 sb_freeze_unlock(sb, SB_FREEZE_FS); 1733 - wake_up(&sb->s_writers.wait_unfrozen); 1734 1735 deactivate_locked_super(sb); 1735 1736 return ret; 1736 1737 } ··· 1775 1778 sb->s_writers.frozen = SB_UNFROZEN; 1776 1779 sb_freeze_unlock(sb, SB_FREEZE_FS); 1777 1780 out: 1778 - wake_up(&sb->s_writers.wait_unfrozen); 1779 1781 deactivate_locked_super(sb); 1780 1782 return 0; 1781 1783 }
+1 -5
fs/udf/balloc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * balloc.c 3 4 * ··· 6 5 * Block allocation handling routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1999-2001 Ben Fennema 15 9 * (C) 1999 Stelias Computing Inc 16 10 *
+1 -5
fs/udf/dir.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * dir.c 3 4 * ··· 6 5 * Directory handling routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1998-2004 Ben Fennema 15 9 * 16 10 * HISTORY
+1 -5
fs/udf/directory.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * directory.c 3 4 * 4 5 * PURPOSE 5 6 * Directory related functions 6 7 * 7 - * COPYRIGHT 8 - * This file is distributed under the terms of the GNU General Public 9 - * License (GPL). Copies of the GPL can be obtained from: 10 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 11 - * Each contributing author retains all rights to their own work. 12 8 */ 13 9 14 10 #include "udfdecl.h"
+1 -5
fs/udf/file.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * file.c 3 4 * ··· 6 5 * File handling routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1998-1999 Dave Boynton 15 9 * (C) 1998-2004 Ben Fennema 16 10 * (C) 1999-2000 Stelias Computing Inc
+1 -5
fs/udf/ialloc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * ialloc.c 3 4 * ··· 6 5 * Inode allocation handling routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1998-2001 Ben Fennema 15 9 * 16 10 * HISTORY
+1 -5
fs/udf/inode.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * inode.c 3 4 * ··· 6 5 * Inode handling routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1998 Dave Boynton 15 9 * (C) 1998-2004 Ben Fennema 16 10 * (C) 1999-2000 Stelias Computing Inc
+1 -5
fs/udf/lowlevel.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * lowlevel.c 3 4 * ··· 6 5 * Low Level Device Routines for the UDF filesystem 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1999-2001 Ben Fennema 15 9 * 16 10 * HISTORY
+1 -5
fs/udf/misc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * misc.c 3 4 * ··· 6 5 * Miscellaneous routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1998 Dave Boynton 15 9 * (C) 1998-2004 Ben Fennema 16 10 * (C) 1999-2000 Stelias Computing Inc
+1 -5
fs/udf/namei.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * namei.c 3 4 * ··· 6 5 * Inode name handling routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1998-2004 Ben Fennema 15 9 * (C) 1999-2000 Stelias Computing Inc 16 10 *
+1 -5
fs/udf/partition.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * partition.c 3 4 * ··· 6 5 * Partition handling routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1998-2001 Ben Fennema 15 9 * 16 10 * HISTORY
+1 -5
fs/udf/super.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * super.c 3 4 * ··· 16 15 * https://www.iso.org/ 17 16 * 18 17 * COPYRIGHT 19 - * This file is distributed under the terms of the GNU General Public 20 - * License (GPL). Copies of the GPL can be obtained from: 21 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 22 - * Each contributing author retains all rights to their own work. 23 - * 24 18 * (C) 1998 Dave Boynton 25 19 * (C) 1998-2004 Ben Fennema 26 20 * (C) 2000 Stelias Computing Inc
+1 -5
fs/udf/symlink.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * symlink.c 3 4 * ··· 6 5 * Symlink handling routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1998-2001 Ben Fennema 15 9 * (C) 1999 Stelias Computing Inc 16 10 *
+1 -5
fs/udf/truncate.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * truncate.c 3 4 * ··· 6 5 * Truncate handling routines for the OSTA-UDF(tm) filesystem. 7 6 * 8 7 * COPYRIGHT 9 - * This file is distributed under the terms of the GNU General Public 10 - * License (GPL). Copies of the GPL can be obtained from: 11 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 12 - * Each contributing author retains all rights to their own work. 13 - * 14 8 * (C) 1999-2004 Ben Fennema 15 9 * (C) 1999 Stelias Computing Inc 16 10 *
+2 -16
fs/udf/udftime.c
··· 1 + // SPDX-License-Identifier: LGPL-2.0+ 1 2 /* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. 2 3 This file is part of the GNU C Library. 3 - Contributed by Paul Eggert (eggert@twinsun.com). 4 - 5 - The GNU C Library is free software; you can redistribute it and/or 6 - modify it under the terms of the GNU Library General Public License as 7 - published by the Free Software Foundation; either version 2 of the 8 - License, or (at your option) any later version. 9 - 10 - The GNU C Library is distributed in the hope that it will be useful, 11 - but WITHOUT ANY WARRANTY; without even the implied warranty of 12 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 - Library General Public License for more details. 14 - 15 - You should have received a copy of the GNU Library General Public 16 - License along with the GNU C Library; see the file COPYING.LIB. If not, 17 - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 - Boston, MA 02111-1307, USA. */ 4 + Contributed by Paul Eggert (eggert@twinsun.com). */ 19 5 20 6 /* 21 7 * dgb 10/02/98: ripped this from glibc source to help convert timestamps
+2 -6
fs/udf/unicode.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 2 3 * unicode.c 3 4 * ··· 12 11 * UTF-8 is explained in the IETF RFC XXXX. 13 12 * ftp://ftp.internic.net/rfc/rfcxxxx.txt 14 13 * 15 - * COPYRIGHT 16 - * This file is distributed under the terms of the GNU General Public 17 - * License (GPL). Copies of the GPL can be obtained from: 18 - * ftp://prep.ai.mit.edu/pub/gnu/GPL 19 - * Each contributing author retains all rights to their own work. 20 14 */ 21 15 22 16 #include "udfdecl.h" ··· 243 247 } 244 248 245 249 if (translate) { 246 - if (str_o_len <= 2 && str_o[0] == '.' && 250 + if (str_o_len > 0 && str_o_len <= 2 && str_o[0] == '.' && 247 251 (str_o_len == 1 || str_o[1] == '.')) 248 252 needsCRC = 1; 249 253 if (needsCRC) {
+4
include/linux/buffer_head.h
··· 217 217 void invalidate_inode_buffers(struct inode *); 218 218 int remove_inode_buffers(struct inode *inode); 219 219 int sync_mapping_buffers(struct address_space *mapping); 220 + int generic_buffers_fsync_noflush(struct file *file, loff_t start, loff_t end, 221 + bool datasync); 222 + int generic_buffers_fsync(struct file *file, loff_t start, loff_t end, 223 + bool datasync); 220 224 void clean_bdev_aliases(struct block_device *bdev, sector_t block, 221 225 sector_t len); 222 226 static inline void clean_bdev_bh_alias(struct buffer_head *bh)
-1
include/linux/fs.h
··· 1148 1148 1149 1149 struct sb_writers { 1150 1150 int frozen; /* Is sb frozen? */ 1151 - wait_queue_head_t wait_unfrozen; /* wait for thaw */ 1152 1151 struct percpu_rw_semaphore rw_sem[SB_FREEZE_LEVELS]; 1153 1152 }; 1154 1153