| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: msdosfs_fat.c,v 1.32 2018/01/27 03:54:01 sevan Exp $ */ | | 1 | /* $NetBSD: msdosfs_fat.c,v 1.33 2018/07/25 22:07:59 kamil Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. | | 4 | * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. |
5 | * Copyright (C) 1994, 1995, 1997 TooLs GmbH. | | 5 | * Copyright (C) 1994, 1995, 1997 TooLs GmbH. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). | | 7 | * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below). |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -42,27 +42,27 @@ | | | @@ -42,27 +42,27 @@ |
42 | * The author supplies this software to be publicly redistributed on the | | 42 | * The author supplies this software to be publicly redistributed on the |
43 | * understanding that the author is not responsible for the correct | | 43 | * understanding that the author is not responsible for the correct |
44 | * functioning of this software in any circumstances and is not liable for | | 44 | * functioning of this software in any circumstances and is not liable for |
45 | * any damages caused by this software. | | 45 | * any damages caused by this software. |
46 | * | | 46 | * |
47 | * October 1992 | | 47 | * October 1992 |
48 | */ | | 48 | */ |
49 | | | 49 | |
50 | #if HAVE_NBTOOL_CONFIG_H | | 50 | #if HAVE_NBTOOL_CONFIG_H |
51 | #include "nbtool_config.h" | | 51 | #include "nbtool_config.h" |
52 | #endif | | 52 | #endif |
53 | | | 53 | |
54 | #include <sys/cdefs.h> | | 54 | #include <sys/cdefs.h> |
55 | __KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.32 2018/01/27 03:54:01 sevan Exp $"); | | 55 | __KERNEL_RCSID(0, "$NetBSD: msdosfs_fat.c,v 1.33 2018/07/25 22:07:59 kamil Exp $"); |
56 | | | 56 | |
57 | /* | | 57 | /* |
58 | * kernel include files. | | 58 | * kernel include files. |
59 | */ | | 59 | */ |
60 | #include <sys/param.h> | | 60 | #include <sys/param.h> |
61 | #include <sys/file.h> | | 61 | #include <sys/file.h> |
62 | #ifdef _KERNEL | | 62 | #ifdef _KERNEL |
63 | #include <sys/mount.h> /* to define statvfs structure */ | | 63 | #include <sys/mount.h> /* to define statvfs structure */ |
64 | #include <sys/errno.h> | | 64 | #include <sys/errno.h> |
65 | #include <sys/systm.h> | | 65 | #include <sys/systm.h> |
66 | #include <sys/kauth.h> | | 66 | #include <sys/kauth.h> |
67 | #include <sys/dirent.h> | | 67 | #include <sys/dirent.h> |
68 | #include <sys/namei.h> | | 68 | #include <sys/namei.h> |
| @@ -399,27 +399,27 @@ updatefats(struct msdosfsmount *pmp, str | | | @@ -399,27 +399,27 @@ updatefats(struct msdosfsmount *pmp, str |
399 | int i, error; | | 399 | int i, error; |
400 | struct buf *bpn; | | 400 | struct buf *bpn; |
401 | | | 401 | |
402 | DPRINTF(("%s(pmp %p, bp %p, fatbn %lu)\n", __func__, pmp, bp, fatbn)); | | 402 | DPRINTF(("%s(pmp %p, bp %p, fatbn %lu)\n", __func__, pmp, bp, fatbn)); |
403 | | | 403 | |
404 | /* | | 404 | /* |
405 | * If we have an FSInfo block, update it. | | 405 | * If we have an FSInfo block, update it. |
406 | */ | | 406 | */ |
407 | if (pmp->pm_fsinfo) { | | 407 | if (pmp->pm_fsinfo) { |
408 | u_long cn = pmp->pm_nxtfree; | | 408 | u_long cn = pmp->pm_nxtfree; |
409 | | | 409 | |
410 | if (pmp->pm_freeclustercount | | 410 | if (pmp->pm_freeclustercount |
411 | && (pmp->pm_inusemap[cn / N_INUSEBITS] | | 411 | && (pmp->pm_inusemap[cn / N_INUSEBITS] |
412 | & (1 << (cn % N_INUSEBITS)))) { | | 412 | & (1U << (cn % N_INUSEBITS)))) { |
413 | /* | | 413 | /* |
414 | * The cluster indicated in FSInfo isn't free | | 414 | * The cluster indicated in FSInfo isn't free |
415 | * any longer. Got get a new free one. | | 415 | * any longer. Got get a new free one. |
416 | */ | | 416 | */ |
417 | for (cn = 0; cn < pmp->pm_maxcluster; cn++) | | 417 | for (cn = 0; cn < pmp->pm_maxcluster; cn++) |
418 | if (pmp->pm_inusemap[cn / N_INUSEBITS] != (u_int)-1) | | 418 | if (pmp->pm_inusemap[cn / N_INUSEBITS] != (u_int)-1) |
419 | break; | | 419 | break; |
420 | pmp->pm_nxtfree = cn | | 420 | pmp->pm_nxtfree = cn |
421 | + ffs(pmp->pm_inusemap[cn / N_INUSEBITS] | | 421 | + ffs(pmp->pm_inusemap[cn / N_INUSEBITS] |
422 | ^ (u_int)-1) - 1; | | 422 | ^ (u_int)-1) - 1; |
423 | } | | 423 | } |
424 | /* | | 424 | /* |
425 | * XXX If the fsinfo block is stored on media with | | 425 | * XXX If the fsinfo block is stored on media with |
| @@ -499,36 +499,36 @@ updatefats(struct msdosfsmount *pmp, str | | | @@ -499,36 +499,36 @@ updatefats(struct msdosfsmount *pmp, str |
499 | * | | 499 | * |
500 | * +----+----+----+ +----+----+----+ | | 500 | * +----+----+----+ +----+----+----+ |
501 | * | 3 0 1 | | 4 5 2 | | | 501 | * | 3 0 1 | | 4 5 2 | |
502 | * +----+----+----+ +----+----+----+ | | 502 | * +----+----+----+ +----+----+----+ |
503 | * cluster n cluster n+1 | | 503 | * cluster n cluster n+1 |
504 | * | | 504 | * |
505 | * Where n is even. m = n + (n >> 2) | | 505 | * Where n is even. m = n + (n >> 2) |
506 | * | | 506 | * |
507 | */ | | 507 | */ |
508 | static inline void | | 508 | static inline void |
509 | usemap_alloc(struct msdosfsmount *pmp, u_long cn) | | 509 | usemap_alloc(struct msdosfsmount *pmp, u_long cn) |
510 | { | | 510 | { |
511 | | | 511 | |
512 | pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS); | | 512 | pmp->pm_inusemap[cn / N_INUSEBITS] |= 1U << (cn % N_INUSEBITS); |
513 | pmp->pm_freeclustercount--; | | 513 | pmp->pm_freeclustercount--; |
514 | } | | 514 | } |
515 | | | 515 | |
516 | static inline void | | 516 | static inline void |
517 | usemap_free(struct msdosfsmount *pmp, u_long cn) | | 517 | usemap_free(struct msdosfsmount *pmp, u_long cn) |
518 | { | | 518 | { |
519 | | | 519 | |
520 | pmp->pm_freeclustercount++; | | 520 | pmp->pm_freeclustercount++; |
521 | pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1 << (cn % N_INUSEBITS)); | | 521 | pmp->pm_inusemap[cn / N_INUSEBITS] &= ~(1U << (cn % N_INUSEBITS)); |
522 | } | | 522 | } |
523 | | | 523 | |
524 | int | | 524 | int |
525 | clusterfree(struct msdosfsmount *pmp, u_long cluster, u_long *oldcnp) | | 525 | clusterfree(struct msdosfsmount *pmp, u_long cluster, u_long *oldcnp) |
526 | { | | 526 | { |
527 | int error; | | 527 | int error; |
528 | u_long oldcn; | | 528 | u_long oldcn; |
529 | | | 529 | |
530 | usemap_free(pmp, cluster); | | 530 | usemap_free(pmp, cluster); |
531 | error = fatentry(FAT_GET_AND_SET, pmp, cluster, &oldcn, MSDOSFSFREE); | | 531 | error = fatentry(FAT_GET_AND_SET, pmp, cluster, &oldcn, MSDOSFSFREE); |
532 | if (error) { | | 532 | if (error) { |
533 | usemap_alloc(pmp, cluster); | | 533 | usemap_alloc(pmp, cluster); |
534 | return (error); | | 534 | return (error); |
| @@ -731,27 +731,27 @@ fatchain(struct msdosfsmount *pmp, u_lon | | | @@ -731,27 +731,27 @@ fatchain(struct msdosfsmount *pmp, u_lon |
731 | * count - maximum interesting length | | 731 | * count - maximum interesting length |
732 | */ | | 732 | */ |
733 | int | | 733 | int |
734 | chainlength(struct msdosfsmount *pmp, u_long start, u_long count) | | 734 | chainlength(struct msdosfsmount *pmp, u_long start, u_long count) |
735 | { | | 735 | { |
736 | u_long idx, max_idx; | | 736 | u_long idx, max_idx; |
737 | u_int map; | | 737 | u_int map; |
738 | u_long len; | | 738 | u_long len; |
739 | | | 739 | |
740 | max_idx = pmp->pm_maxcluster / N_INUSEBITS; | | 740 | max_idx = pmp->pm_maxcluster / N_INUSEBITS; |
741 | idx = start / N_INUSEBITS; | | 741 | idx = start / N_INUSEBITS; |
742 | start %= N_INUSEBITS; | | 742 | start %= N_INUSEBITS; |
743 | map = pmp->pm_inusemap[idx]; | | 743 | map = pmp->pm_inusemap[idx]; |
744 | map &= ~((1 << start) - 1); | | 744 | map &= ~((1U << start) - 1); |
745 | if (map) { | | 745 | if (map) { |
746 | len = ffs(map) - 1 - start; | | 746 | len = ffs(map) - 1 - start; |
747 | return (len > count ? count : len); | | 747 | return (len > count ? count : len); |
748 | } | | 748 | } |
749 | len = N_INUSEBITS - start; | | 749 | len = N_INUSEBITS - start; |
750 | if (len >= count) | | 750 | if (len >= count) |
751 | return (count); | | 751 | return (count); |
752 | while (++idx <= max_idx) { | | 752 | while (++idx <= max_idx) { |
753 | if (len >= count) | | 753 | if (len >= count) |
754 | break; | | 754 | break; |
755 | if ((map = pmp->pm_inusemap[idx]) != 0) { | | 755 | if ((map = pmp->pm_inusemap[idx]) != 0) { |
756 | len += ffs(map) - 1; | | 756 | len += ffs(map) - 1; |
757 | break; | | 757 | break; |
| @@ -827,44 +827,44 @@ clusteralloc(struct msdosfsmount *pmp, u | | | @@ -827,44 +827,44 @@ clusteralloc(struct msdosfsmount *pmp, u |
827 | len = 0; | | 827 | len = 0; |
828 | } | | 828 | } |
829 | | | 829 | |
830 | /* | | 830 | /* |
831 | * Start at a (pseudo) random place to maximize cluster runs | | 831 | * Start at a (pseudo) random place to maximize cluster runs |
832 | * under multiple writers. | | 832 | * under multiple writers. |
833 | */ | | 833 | */ |
834 | newst = (start * 1103515245 + 12345) % (pmp->pm_maxcluster + 1); | | 834 | newst = (start * 1103515245 + 12345) % (pmp->pm_maxcluster + 1); |
835 | foundl = 0; | | 835 | foundl = 0; |
836 | | | 836 | |
837 | for (cn = newst; cn <= pmp->pm_maxcluster;) { | | 837 | for (cn = newst; cn <= pmp->pm_maxcluster;) { |
838 | idx = cn / N_INUSEBITS; | | 838 | idx = cn / N_INUSEBITS; |
839 | map = pmp->pm_inusemap[idx]; | | 839 | map = pmp->pm_inusemap[idx]; |
840 | map |= (1 << (cn % N_INUSEBITS)) - 1; | | 840 | map |= (1U << (cn % N_INUSEBITS)) - 1; |
841 | if (map != (u_int)-1) { | | 841 | if (map != (u_int)-1) { |
842 | cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1; | | 842 | cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1; |
843 | if ((l = chainlength(pmp, cn, count)) >= count) | | 843 | if ((l = chainlength(pmp, cn, count)) >= count) |
844 | return (chainalloc(pmp, cn, count, fillwith, retcluster, got)); | | 844 | return (chainalloc(pmp, cn, count, fillwith, retcluster, got)); |
845 | if (l > foundl) { | | 845 | if (l > foundl) { |
846 | foundcn = cn; | | 846 | foundcn = cn; |
847 | foundl = l; | | 847 | foundl = l; |
848 | } | | 848 | } |
849 | cn += l + 1; | | 849 | cn += l + 1; |
850 | continue; | | 850 | continue; |
851 | } | | 851 | } |
852 | cn += N_INUSEBITS - cn % N_INUSEBITS; | | 852 | cn += N_INUSEBITS - cn % N_INUSEBITS; |
853 | } | | 853 | } |
854 | for (cn = 0; cn < newst;) { | | 854 | for (cn = 0; cn < newst;) { |
855 | idx = cn / N_INUSEBITS; | | 855 | idx = cn / N_INUSEBITS; |
856 | map = pmp->pm_inusemap[idx]; | | 856 | map = pmp->pm_inusemap[idx]; |
857 | map |= (1 << (cn % N_INUSEBITS)) - 1; | | 857 | map |= (1U << (cn % N_INUSEBITS)) - 1; |
858 | if (map != (u_int)-1) { | | 858 | if (map != (u_int)-1) { |
859 | cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1; | | 859 | cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1; |
860 | if ((l = chainlength(pmp, cn, count)) >= count) | | 860 | if ((l = chainlength(pmp, cn, count)) >= count) |
861 | return (chainalloc(pmp, cn, count, fillwith, retcluster, got)); | | 861 | return (chainalloc(pmp, cn, count, fillwith, retcluster, got)); |
862 | if (l > foundl) { | | 862 | if (l > foundl) { |
863 | foundcn = cn; | | 863 | foundcn = cn; |
864 | foundl = l; | | 864 | foundl = l; |
865 | } | | 865 | } |
866 | cn += l + 1; | | 866 | cn += l + 1; |
867 | continue; | | 867 | continue; |
868 | } | | 868 | } |
869 | cn += N_INUSEBITS - cn % N_INUSEBITS; | | 869 | cn += N_INUSEBITS - cn % N_INUSEBITS; |
870 | } | | 870 | } |