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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'hpfs-patches' (patches from Mikulas Patocka)

Merge hpfs updates from Mikulas Patocka.

Mainly fstrim support, with some minor other cleanups.

These were actually sent during the merge window, but I wanted to wait
for the FSTRIM compat handling cleanup before applying them. Mikulas
sent that earlier today.

* emailed patches from Mikulas Patocka <mikulas@twibright.com>:
hpfs: hpfs_error: Remove static buffer, use vsprintf extension %pV instead
hpfs: kstrdup() out of memory handling
hpfs: Remove unessary cast
hpfs: add fstrim support

+141 -7
+95
fs/hpfs/alloc.c
··· 484 484 a->btree.first_free = cpu_to_le16(8); 485 485 return a; 486 486 } 487 + 488 + static unsigned find_run(__le32 *bmp, unsigned *idx) 489 + { 490 + unsigned len; 491 + while (tstbits(bmp, *idx, 1)) { 492 + (*idx)++; 493 + if (unlikely(*idx >= 0x4000)) 494 + return 0; 495 + } 496 + len = 1; 497 + while (!tstbits(bmp, *idx + len, 1)) 498 + len++; 499 + return len; 500 + } 501 + 502 + static int do_trim(struct super_block *s, secno start, unsigned len, secno limit_start, secno limit_end, unsigned minlen, unsigned *result) 503 + { 504 + int err; 505 + secno end; 506 + if (fatal_signal_pending(current)) 507 + return -EINTR; 508 + end = start + len; 509 + if (start < limit_start) 510 + start = limit_start; 511 + if (end > limit_end) 512 + end = limit_end; 513 + if (start >= end) 514 + return 0; 515 + if (end - start < minlen) 516 + return 0; 517 + err = sb_issue_discard(s, start, end - start, GFP_NOFS, 0); 518 + if (err) 519 + return err; 520 + *result += end - start; 521 + return 0; 522 + } 523 + 524 + int hpfs_trim_fs(struct super_block *s, u64 start, u64 end, u64 minlen, unsigned *result) 525 + { 526 + int err = 0; 527 + struct hpfs_sb_info *sbi = hpfs_sb(s); 528 + unsigned idx, len, start_bmp, end_bmp; 529 + __le32 *bmp; 530 + struct quad_buffer_head qbh; 531 + 532 + *result = 0; 533 + if (!end || end > sbi->sb_fs_size) 534 + end = sbi->sb_fs_size; 535 + if (start >= sbi->sb_fs_size) 536 + return 0; 537 + if (minlen > 0x4000) 538 + return 0; 539 + if (start < sbi->sb_dirband_start + sbi->sb_dirband_size && end > sbi->sb_dirband_start) { 540 + hpfs_lock(s); 541 + if (s->s_flags & MS_RDONLY) { 542 + err = -EROFS; 543 + goto unlock_1; 544 + } 545 + if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) { 546 + err = -EIO; 547 + goto unlock_1; 548 + } 549 + idx = 0; 550 + while ((len = find_run(bmp, &idx)) && !err) { 551 + err = do_trim(s, sbi->sb_dirband_start + idx * 4, len * 4, start, end, minlen, result); 552 + idx += len; 553 + } 554 + hpfs_brelse4(&qbh); 555 + unlock_1: 556 + hpfs_unlock(s); 557 + } 558 + start_bmp = start >> 14; 559 + end_bmp = (end + 0x3fff) >> 14; 560 + while (start_bmp < end_bmp && !err) { 561 + hpfs_lock(s); 562 + if (s->s_flags & MS_RDONLY) { 563 + err = -EROFS; 564 + goto unlock_2; 565 + } 566 + if (!(bmp = hpfs_map_bitmap(s, start_bmp, &qbh, "trim"))) { 567 + err = -EIO; 568 + goto unlock_2; 569 + } 570 + idx = 0; 571 + while ((len = find_run(bmp, &idx)) && !err) { 572 + err = do_trim(s, (start_bmp << 14) + idx, len, start, end, minlen, result); 573 + idx += len; 574 + } 575 + hpfs_brelse4(&qbh); 576 + unlock_2: 577 + hpfs_unlock(s); 578 + start_bmp++; 579 + } 580 + return err; 581 + }
+1
fs/hpfs/dir.c
··· 327 327 .iterate = hpfs_readdir, 328 328 .release = hpfs_dir_release, 329 329 .fsync = hpfs_file_fsync, 330 + .unlocked_ioctl = hpfs_ioctl, 330 331 };
+1
fs/hpfs/file.c
··· 203 203 .release = hpfs_file_release, 204 204 .fsync = hpfs_file_fsync, 205 205 .splice_read = generic_file_splice_read, 206 + .unlocked_ioctl = hpfs_ioctl, 206 207 }; 207 208 208 209 const struct inode_operations hpfs_file_iops =
+4
fs/hpfs/hpfs_fn.h
··· 18 18 #include <linux/pagemap.h> 19 19 #include <linux/buffer_head.h> 20 20 #include <linux/slab.h> 21 + #include <linux/sched.h> 22 + #include <linux/blkdev.h> 21 23 #include <asm/unaligned.h> 22 24 23 25 #include "hpfs.h" ··· 202 200 struct dnode *hpfs_alloc_dnode(struct super_block *, secno, dnode_secno *, struct quad_buffer_head *); 203 201 struct fnode *hpfs_alloc_fnode(struct super_block *, secno, fnode_secno *, struct buffer_head **); 204 202 struct anode *hpfs_alloc_anode(struct super_block *, secno, anode_secno *, struct buffer_head **); 203 + int hpfs_trim_fs(struct super_block *, u64, u64, u64, unsigned *); 205 204 206 205 /* anode.c */ 207 206 ··· 321 318 void hpfs_error(struct super_block *, const char *, ...); 322 319 int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *); 323 320 unsigned hpfs_get_free_dnodes(struct super_block *); 321 + long hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg); 324 322 325 323 /* 326 324 * local time (HPFS) to GMT (Unix)
+40 -7
fs/hpfs/super.c
··· 52 52 } 53 53 54 54 /* Filesystem error... */ 55 - static char err_buf[1024]; 56 - 57 55 void hpfs_error(struct super_block *s, const char *fmt, ...) 58 56 { 57 + struct va_format vaf; 59 58 va_list args; 60 59 61 60 va_start(args, fmt); 62 - vsnprintf(err_buf, sizeof(err_buf), fmt, args); 61 + 62 + vaf.fmt = fmt; 63 + vaf.va = &args; 64 + 65 + pr_err("filesystem error: %pV", &vaf); 66 + 63 67 va_end(args); 64 68 65 - pr_err("filesystem error: %s", err_buf); 66 69 if (!hpfs_sb(s)->sb_was_error) { 67 70 if (hpfs_sb(s)->sb_err == 2) { 68 71 pr_cont("; crashing the system because you wanted it\n"); ··· 199 196 return 0; 200 197 } 201 198 199 + 200 + long hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg) 201 + { 202 + switch (cmd) { 203 + case FITRIM: { 204 + struct fstrim_range range; 205 + secno n_trimmed; 206 + int r; 207 + if (!capable(CAP_SYS_ADMIN)) 208 + return -EPERM; 209 + if (copy_from_user(&range, (struct fstrim_range __user *)arg, sizeof(range))) 210 + return -EFAULT; 211 + r = hpfs_trim_fs(file_inode(file)->i_sb, range.start >> 9, (range.start + range.len) >> 9, (range.minlen + 511) >> 9, &n_trimmed); 212 + if (r) 213 + return r; 214 + range.len = (u64)n_trimmed << 9; 215 + if (copy_to_user((struct fstrim_range __user *)arg, &range, sizeof(range))) 216 + return -EFAULT; 217 + return 0; 218 + } 219 + default: { 220 + return -ENOIOCTLCMD; 221 + } 222 + } 223 + } 224 + 225 + 202 226 static struct kmem_cache * hpfs_inode_cachep; 203 227 204 228 static struct inode *hpfs_alloc_inode(struct super_block *sb) 205 229 { 206 230 struct hpfs_inode_info *ei; 207 - ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, GFP_NOFS); 231 + ei = kmem_cache_alloc(hpfs_inode_cachep, GFP_NOFS); 208 232 if (!ei) 209 233 return NULL; 210 234 ei->vfs_inode.i_version = 1; ··· 454 424 int o; 455 425 struct hpfs_sb_info *sbi = hpfs_sb(s); 456 426 char *new_opts = kstrdup(data, GFP_KERNEL); 457 - 427 + 428 + if (!new_opts) 429 + return -ENOMEM; 430 + 458 431 sync_filesystem(s); 459 432 460 433 *flags |= MS_NOATIME; 461 - 434 + 462 435 hpfs_lock(s); 463 436 uid = sbi->sb_uid; gid = sbi->sb_gid; 464 437 umask = 0777 & ~sbi->sb_mode;