~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/hpfs/alloc.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /fs/hpfs/alloc.c (Version linux-6.12-rc7) and /fs/hpfs/alloc.c (Version linux-4.10.17)


  1 // SPDX-License-Identifier: GPL-2.0            << 
  2 /*                                                  1 /*
  3  *  linux/fs/hpfs/alloc.c                           2  *  linux/fs/hpfs/alloc.c
  4  *                                                  3  *
  5  *  Mikulas Patocka (mikulas@artax.karlin.mff.      4  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
  6  *                                                  5  *
  7  *  HPFS bitmap operations                          6  *  HPFS bitmap operations
  8  */                                                 7  */
  9                                                     8 
 10 #include "hpfs_fn.h"                                9 #include "hpfs_fn.h"
 11                                                    10 
 12 static void hpfs_claim_alloc(struct super_bloc     11 static void hpfs_claim_alloc(struct super_block *s, secno sec)
 13 {                                                  12 {
 14         struct hpfs_sb_info *sbi = hpfs_sb(s);     13         struct hpfs_sb_info *sbi = hpfs_sb(s);
 15         if (sbi->sb_n_free != (unsigned)-1) {      14         if (sbi->sb_n_free != (unsigned)-1) {
 16                 if (unlikely(!sbi->sb_n_free))     15                 if (unlikely(!sbi->sb_n_free)) {
 17                         hpfs_error(s, "free co     16                         hpfs_error(s, "free count underflow, allocating sector %08x", sec);
 18                         sbi->sb_n_free = -1;       17                         sbi->sb_n_free = -1;
 19                         return;                    18                         return;
 20                 }                                  19                 }
 21                 sbi->sb_n_free--;                  20                 sbi->sb_n_free--;
 22         }                                          21         }
 23 }                                                  22 }
 24                                                    23 
 25 static void hpfs_claim_free(struct super_block     24 static void hpfs_claim_free(struct super_block *s, secno sec)
 26 {                                                  25 {
 27         struct hpfs_sb_info *sbi = hpfs_sb(s);     26         struct hpfs_sb_info *sbi = hpfs_sb(s);
 28         if (sbi->sb_n_free != (unsigned)-1) {      27         if (sbi->sb_n_free != (unsigned)-1) {
 29                 if (unlikely(sbi->sb_n_free >=     28                 if (unlikely(sbi->sb_n_free >= sbi->sb_fs_size)) {
 30                         hpfs_error(s, "free co     29                         hpfs_error(s, "free count overflow, freeing sector %08x", sec);
 31                         sbi->sb_n_free = -1;       30                         sbi->sb_n_free = -1;
 32                         return;                    31                         return;
 33                 }                                  32                 }
 34                 sbi->sb_n_free++;                  33                 sbi->sb_n_free++;
 35         }                                          34         }
 36 }                                                  35 }
 37                                                    36 
 38 static void hpfs_claim_dirband_alloc(struct su     37 static void hpfs_claim_dirband_alloc(struct super_block *s, secno sec)
 39 {                                                  38 {
 40         struct hpfs_sb_info *sbi = hpfs_sb(s);     39         struct hpfs_sb_info *sbi = hpfs_sb(s);
 41         if (sbi->sb_n_free_dnodes != (unsigned     40         if (sbi->sb_n_free_dnodes != (unsigned)-1) {
 42                 if (unlikely(!sbi->sb_n_free_d     41                 if (unlikely(!sbi->sb_n_free_dnodes)) {
 43                         hpfs_error(s, "dirband     42                         hpfs_error(s, "dirband free count underflow, allocating sector %08x", sec);
 44                         sbi->sb_n_free_dnodes      43                         sbi->sb_n_free_dnodes = -1;
 45                         return;                    44                         return;
 46                 }                                  45                 }
 47                 sbi->sb_n_free_dnodes--;           46                 sbi->sb_n_free_dnodes--;
 48         }                                          47         }
 49 }                                                  48 }
 50                                                    49 
 51 static void hpfs_claim_dirband_free(struct sup     50 static void hpfs_claim_dirband_free(struct super_block *s, secno sec)
 52 {                                                  51 {
 53         struct hpfs_sb_info *sbi = hpfs_sb(s);     52         struct hpfs_sb_info *sbi = hpfs_sb(s);
 54         if (sbi->sb_n_free_dnodes != (unsigned     53         if (sbi->sb_n_free_dnodes != (unsigned)-1) {
 55                 if (unlikely(sbi->sb_n_free_dn     54                 if (unlikely(sbi->sb_n_free_dnodes >= sbi->sb_dirband_size / 4)) {
 56                         hpfs_error(s, "dirband     55                         hpfs_error(s, "dirband free count overflow, freeing sector %08x", sec);
 57                         sbi->sb_n_free_dnodes      56                         sbi->sb_n_free_dnodes = -1;
 58                         return;                    57                         return;
 59                 }                                  58                 }
 60                 sbi->sb_n_free_dnodes++;           59                 sbi->sb_n_free_dnodes++;
 61         }                                          60         }
 62 }                                                  61 }
 63                                                    62 
 64 /*                                                 63 /*
 65  * Check if a sector is allocated in bitmap        64  * Check if a sector is allocated in bitmap
 66  * This is really slow. Turned on only if chk=     65  * This is really slow. Turned on only if chk==2
 67  */                                                66  */
 68                                                    67 
 69 static int chk_if_allocated(struct super_block     68 static int chk_if_allocated(struct super_block *s, secno sec, char *msg)
 70 {                                                  69 {
 71         struct quad_buffer_head qbh;               70         struct quad_buffer_head qbh;
 72         __le32 *bmp;                               71         __le32 *bmp;
 73         if (!(bmp = hpfs_map_bitmap(s, sec >>      72         if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "chk"))) goto fail;
 74         if ((le32_to_cpu(bmp[(sec & 0x3fff) >>     73         if ((le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f)) & 1) {
 75                 hpfs_error(s, "sector '%s' - %     74                 hpfs_error(s, "sector '%s' - %08x not allocated in bitmap", msg, sec);
 76                 goto fail1;                        75                 goto fail1;
 77         }                                          76         }
 78         hpfs_brelse4(&qbh);                        77         hpfs_brelse4(&qbh);
 79         if (sec >= hpfs_sb(s)->sb_dirband_star     78         if (sec >= hpfs_sb(s)->sb_dirband_start && sec < hpfs_sb(s)->sb_dirband_start + hpfs_sb(s)->sb_dirband_size) {
 80                 unsigned ssec = (sec - hpfs_sb     79                 unsigned ssec = (sec - hpfs_sb(s)->sb_dirband_start) / 4;
 81                 if (!(bmp = hpfs_map_dnode_bit     80                 if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) goto fail;
 82                 if ((le32_to_cpu(bmp[ssec >> 5     81                 if ((le32_to_cpu(bmp[ssec >> 5]) >> (ssec & 0x1f)) & 1) {
 83                         hpfs_error(s, "sector      82                         hpfs_error(s, "sector '%s' - %08x not allocated in directory bitmap", msg, sec);
 84                         goto fail1;                83                         goto fail1;
 85                 }                                  84                 }
 86                 hpfs_brelse4(&qbh);                85                 hpfs_brelse4(&qbh);
 87         }                                          86         }
 88         return 0;                                  87         return 0;
 89         fail1:                                     88         fail1:
 90         hpfs_brelse4(&qbh);                        89         hpfs_brelse4(&qbh);
 91         fail:                                      90         fail:
 92         return 1;                                  91         return 1;
 93 }                                                  92 }
 94                                                    93 
 95 /*                                                 94 /*
 96  * Check if sector(s) have proper number and a     95  * Check if sector(s) have proper number and additionally check if they're
 97  * allocated in bitmap.                            96  * allocated in bitmap.
 98  */                                                97  */
 99                                                    98         
100 int hpfs_chk_sectors(struct super_block *s, se     99 int hpfs_chk_sectors(struct super_block *s, secno start, int len, char *msg)
101 {                                                 100 {
102         if (start + len < start || start < 0x1    101         if (start + len < start || start < 0x12 ||
103             start + len > hpfs_sb(s)->sb_fs_si    102             start + len > hpfs_sb(s)->sb_fs_size) {
104                 hpfs_error(s, "sector(s) '%s'     103                 hpfs_error(s, "sector(s) '%s' badly placed at %08x", msg, start);
105                 return 1;                         104                 return 1;
106         }                                         105         }
107         if (hpfs_sb(s)->sb_chk>=2) {              106         if (hpfs_sb(s)->sb_chk>=2) {
108                 int i;                            107                 int i;
109                 for (i = 0; i < len; i++)         108                 for (i = 0; i < len; i++)
110                         if (chk_if_allocated(s    109                         if (chk_if_allocated(s, start + i, msg)) return 1;
111         }                                         110         }
112         return 0;                                 111         return 0;
113 }                                                 112 }
114                                                   113 
115 static secno alloc_in_bmp(struct super_block *    114 static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigned forward)
116 {                                                 115 {
117         struct quad_buffer_head qbh;              116         struct quad_buffer_head qbh;
118         __le32 *bmp;                              117         __le32 *bmp;
119         unsigned bs = near & ~0x3fff;             118         unsigned bs = near & ~0x3fff;
120         unsigned nr = (near & 0x3fff) & ~(n -     119         unsigned nr = (near & 0x3fff) & ~(n - 1);
121         /*unsigned mnr;*/                         120         /*unsigned mnr;*/
122         unsigned i, q;                            121         unsigned i, q;
123         int a, b;                                 122         int a, b;
124         secno ret = 0;                            123         secno ret = 0;
125         if (n != 1 && n != 4) {                   124         if (n != 1 && n != 4) {
126                 hpfs_error(s, "Bad allocation     125                 hpfs_error(s, "Bad allocation size: %d", n);
127                 return 0;                         126                 return 0;
128         }                                         127         }
129         if (bs != ~0x3fff) {                      128         if (bs != ~0x3fff) {
130                 if (!(bmp = hpfs_map_bitmap(s,    129                 if (!(bmp = hpfs_map_bitmap(s, near >> 14, &qbh, "aib"))) goto uls;
131         } else {                                  130         } else {
132                 if (!(bmp = hpfs_map_dnode_bit    131                 if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) goto uls;
133         }                                         132         }
134         if (!tstbits(bmp, nr, n + forward)) {     133         if (!tstbits(bmp, nr, n + forward)) {
135                 ret = bs + nr;                    134                 ret = bs + nr;
136                 goto rt;                          135                 goto rt;
137         }                                         136         }
138         q = nr + n; b = 0;                        137         q = nr + n; b = 0;
139         while ((a = tstbits(bmp, q, n + forwar    138         while ((a = tstbits(bmp, q, n + forward)) != 0) {
140                 q += a;                           139                 q += a;
141                 if (n != 1) q = ((q-1)&~(n-1))    140                 if (n != 1) q = ((q-1)&~(n-1))+n;
142                 if (!b) {                         141                 if (!b) {
143                         if (q>>5 != nr>>5) {      142                         if (q>>5 != nr>>5) {
144                                 b = 1;            143                                 b = 1;
145                                 q = nr & 0x1f;    144                                 q = nr & 0x1f;
146                         }                         145                         }
147                 } else if (q > nr) break;         146                 } else if (q > nr) break;
148         }                                         147         }
149         if (!a) {                                 148         if (!a) {
150                 ret = bs + q;                     149                 ret = bs + q;
151                 goto rt;                          150                 goto rt;
152         }                                         151         }
153         nr >>= 5;                                 152         nr >>= 5;
154         /*for (i = nr + 1; i != nr; i++, i &=     153         /*for (i = nr + 1; i != nr; i++, i &= 0x1ff) */
155         i = nr;                                   154         i = nr;
156         do {                                      155         do {
157                 if (!le32_to_cpu(bmp[i])) goto    156                 if (!le32_to_cpu(bmp[i])) goto cont;
158                 if (n + forward >= 0x3f && le3    157                 if (n + forward >= 0x3f && le32_to_cpu(bmp[i]) != 0xffffffff) goto cont;
159                 q = i<<5;                         158                 q = i<<5;
160                 if (i > 0) {                      159                 if (i > 0) {
161                         unsigned k = le32_to_c    160                         unsigned k = le32_to_cpu(bmp[i-1]);
162                         while (k & 0x80000000)    161                         while (k & 0x80000000) {
163                                 q--; k <<= 1;     162                                 q--; k <<= 1;
164                         }                         163                         }
165                 }                                 164                 }
166                 if (n != 1) q = ((q-1)&~(n-1))    165                 if (n != 1) q = ((q-1)&~(n-1))+n;
167                 while ((a = tstbits(bmp, q, n     166                 while ((a = tstbits(bmp, q, n + forward)) != 0) {
168                         q += a;                   167                         q += a;
169                         if (n != 1) q = ((q-1)    168                         if (n != 1) q = ((q-1)&~(n-1))+n;
170                         if (q>>5 > i) break;      169                         if (q>>5 > i) break;
171                 }                                 170                 }
172                 if (!a) {                         171                 if (!a) {
173                         ret = bs + q;             172                         ret = bs + q;
174                         goto rt;                  173                         goto rt;
175                 }                                 174                 }
176                 cont:                             175                 cont:
177                 i++, i &= 0x1ff;                  176                 i++, i &= 0x1ff;
178         } while (i != nr);                        177         } while (i != nr);
179         rt:                                       178         rt:
180         if (ret) {                                179         if (ret) {
181                 if (hpfs_sb(s)->sb_chk && ((re    180                 if (hpfs_sb(s)->sb_chk && ((ret >> 14) != (bs >> 14) || (le32_to_cpu(bmp[(ret & 0x3fff) >> 5]) | ~(((1 << n) - 1) << (ret & 0x1f))) != 0xffffffff)) {
182                         hpfs_error(s, "Allocat    181                         hpfs_error(s, "Allocation doesn't work! Wanted %d, allocated at %08x", n, ret);
183                         ret = 0;                  182                         ret = 0;
184                         goto b;                   183                         goto b;
185                 }                                 184                 }
186                 bmp[(ret & 0x3fff) >> 5] &= cp    185                 bmp[(ret & 0x3fff) >> 5] &= cpu_to_le32(~(((1 << n) - 1) << (ret & 0x1f)));
187                 hpfs_mark_4buffers_dirty(&qbh)    186                 hpfs_mark_4buffers_dirty(&qbh);
188         }                                         187         }
189         b:                                        188         b:
190         hpfs_brelse4(&qbh);                       189         hpfs_brelse4(&qbh);
191         uls:                                      190         uls:
192         return ret;                               191         return ret;
193 }                                                 192 }
194                                                   193 
195 /*                                                194 /*
196  * Allocation strategy: 1) search place near t    195  * Allocation strategy: 1) search place near the sector specified
197  *                      2) search bitmap where    196  *                      2) search bitmap where free sectors last found
198  *                      3) search all bitmaps     197  *                      3) search all bitmaps
199  *                      4) search all bitmaps     198  *                      4) search all bitmaps ignoring number of pre-allocated
200  *                              sectors           199  *                              sectors
201  */                                               200  */
202                                                   201 
203 secno hpfs_alloc_sector(struct super_block *s,    202 secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forward)
204 {                                                 203 {
205         secno sec;                                204         secno sec;
206         int i;                                    205         int i;
207         unsigned n_bmps;                          206         unsigned n_bmps;
208         struct hpfs_sb_info *sbi = hpfs_sb(s);    207         struct hpfs_sb_info *sbi = hpfs_sb(s);
209         int f_p = 0;                              208         int f_p = 0;
210         int near_bmp;                             209         int near_bmp;
211         if (forward < 0) {                        210         if (forward < 0) {
212                 forward = -forward;               211                 forward = -forward;
213                 f_p = 1;                          212                 f_p = 1;
214         }                                         213         }
215         n_bmps = (sbi->sb_fs_size + 0x4000 - 1    214         n_bmps = (sbi->sb_fs_size + 0x4000 - 1) >> 14;
216         if (near && near < sbi->sb_fs_size) {     215         if (near && near < sbi->sb_fs_size) {
217                 if ((sec = alloc_in_bmp(s, nea    216                 if ((sec = alloc_in_bmp(s, near, n, f_p ? forward : forward/4))) goto ret;
218                 near_bmp = near >> 14;            217                 near_bmp = near >> 14;
219         } else near_bmp = n_bmps / 2;             218         } else near_bmp = n_bmps / 2;
220         /*                                        219         /*
221         if (b != -1) {                            220         if (b != -1) {
222                 if ((sec = alloc_in_bmp(s, b<<    221                 if ((sec = alloc_in_bmp(s, b<<14, n, f_p ? forward : forward/2))) {
223                         b &= 0x0fffffff;          222                         b &= 0x0fffffff;
224                         goto ret;                 223                         goto ret;
225                 }                                 224                 }
226                 if (b > 0x10000000) if ((sec =    225                 if (b > 0x10000000) if ((sec = alloc_in_bmp(s, (b&0xfffffff)<<14, n, f_p ? forward : 0))) goto ret;
227         */                                        226         */
228         if (!f_p) if (forward > sbi->sb_max_fw    227         if (!f_p) if (forward > sbi->sb_max_fwd_alloc) forward = sbi->sb_max_fwd_alloc;
229         less_fwd:                                 228         less_fwd:
230         for (i = 0; i < n_bmps; i++) {            229         for (i = 0; i < n_bmps; i++) {
231                 if (near_bmp+i < n_bmps && ((s    230                 if (near_bmp+i < n_bmps && ((sec = alloc_in_bmp(s, (near_bmp+i) << 14, n, forward)))) {
232                         sbi->sb_c_bitmap = nea    231                         sbi->sb_c_bitmap = near_bmp+i;
233                         goto ret;                 232                         goto ret;
234                 }                                 233                 }       
235                 if (!forward) {                   234                 if (!forward) {
236                         if (near_bmp-i-1 >= 0     235                         if (near_bmp-i-1 >= 0 && ((sec = alloc_in_bmp(s, (near_bmp-i-1) << 14, n, forward)))) {
237                                 sbi->sb_c_bitm    236                                 sbi->sb_c_bitmap = near_bmp-i-1;
238                                 goto ret;         237                                 goto ret;
239                         }                         238                         }
240                 } else {                          239                 } else {
241                         if (near_bmp+i >= n_bm    240                         if (near_bmp+i >= n_bmps && ((sec = alloc_in_bmp(s, (near_bmp+i-n_bmps) << 14, n, forward)))) {
242                                 sbi->sb_c_bitm    241                                 sbi->sb_c_bitmap = near_bmp+i-n_bmps;
243                                 goto ret;         242                                 goto ret;
244                         }                         243                         }
245                 }                                 244                 }
246                 if (i == 1 && sbi->sb_c_bitmap    245                 if (i == 1 && sbi->sb_c_bitmap != -1 && ((sec = alloc_in_bmp(s, (sbi->sb_c_bitmap) << 14, n, forward)))) {
247                         goto ret;                 246                         goto ret;
248                 }                                 247                 }
249         }                                         248         }
250         if (!f_p) {                               249         if (!f_p) {
251                 if (forward) {                    250                 if (forward) {
252                         sbi->sb_max_fwd_alloc     251                         sbi->sb_max_fwd_alloc = forward * 3 / 4;
253                         forward /= 2;             252                         forward /= 2;
254                         goto less_fwd;            253                         goto less_fwd;
255                 }                                 254                 }
256         }                                         255         }
257         sec = 0;                                  256         sec = 0;
258         ret:                                      257         ret:
259         if (sec) {                                258         if (sec) {
260                 i = 0;                            259                 i = 0;
261                 do                                260                 do
262                         hpfs_claim_alloc(s, se    261                         hpfs_claim_alloc(s, sec + i);
263                 while (unlikely(++i < n));        262                 while (unlikely(++i < n));
264         }                                         263         }
265         if (sec && f_p) {                         264         if (sec && f_p) {
266                 for (i = 0; i < forward; i++)     265                 for (i = 0; i < forward; i++) {
267                         if (!hpfs_alloc_if_pos    266                         if (!hpfs_alloc_if_possible(s, sec + n + i)) {
268                                 hpfs_error(s,     267                                 hpfs_error(s, "Prealloc doesn't work! Wanted %d, allocated at %08x, can't allocate %d", forward, sec, i);
269                                 sec = 0;          268                                 sec = 0;
270                                 break;            269                                 break;
271                         }                         270                         }
272                 }                                 271                 }
273         }                                         272         }
274         return sec;                               273         return sec;
275 }                                                 274 }
276                                                   275 
277 static secno alloc_in_dirband(struct super_blo    276 static secno alloc_in_dirband(struct super_block *s, secno near)
278 {                                                 277 {
279         unsigned nr = near;                       278         unsigned nr = near;
280         secno sec;                                279         secno sec;
281         struct hpfs_sb_info *sbi = hpfs_sb(s);    280         struct hpfs_sb_info *sbi = hpfs_sb(s);
282         if (nr < sbi->sb_dirband_start)           281         if (nr < sbi->sb_dirband_start)
283                 nr = sbi->sb_dirband_start;       282                 nr = sbi->sb_dirband_start;
284         if (nr >= sbi->sb_dirband_start + sbi-    283         if (nr >= sbi->sb_dirband_start + sbi->sb_dirband_size)
285                 nr = sbi->sb_dirband_start + s    284                 nr = sbi->sb_dirband_start + sbi->sb_dirband_size - 4;
286         nr -= sbi->sb_dirband_start;              285         nr -= sbi->sb_dirband_start;
287         nr >>= 2;                                 286         nr >>= 2;
288         sec = alloc_in_bmp(s, (~0x3fff) | nr,     287         sec = alloc_in_bmp(s, (~0x3fff) | nr, 1, 0);
289         if (!sec) return 0;                       288         if (!sec) return 0;
290         hpfs_claim_dirband_alloc(s, sec);         289         hpfs_claim_dirband_alloc(s, sec);
291         return ((sec & 0x3fff) << 2) + sbi->sb    290         return ((sec & 0x3fff) << 2) + sbi->sb_dirband_start;
292 }                                                 291 }
293                                                   292 
294 /* Alloc sector if it's free */                   293 /* Alloc sector if it's free */
295                                                   294 
296 int hpfs_alloc_if_possible(struct super_block     295 int hpfs_alloc_if_possible(struct super_block *s, secno sec)
297 {                                                 296 {
298         struct quad_buffer_head qbh;              297         struct quad_buffer_head qbh;
299         __le32 *bmp;                              298         __le32 *bmp;
300         if (!(bmp = hpfs_map_bitmap(s, sec >>     299         if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "aip"))) goto end;
301         if (le32_to_cpu(bmp[(sec & 0x3fff) >>     300         if (le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) & (1 << (sec & 0x1f))) {
302                 bmp[(sec & 0x3fff) >> 5] &= cp    301                 bmp[(sec & 0x3fff) >> 5] &= cpu_to_le32(~(1 << (sec & 0x1f)));
303                 hpfs_mark_4buffers_dirty(&qbh)    302                 hpfs_mark_4buffers_dirty(&qbh);
304                 hpfs_brelse4(&qbh);               303                 hpfs_brelse4(&qbh);
305                 hpfs_claim_alloc(s, sec);         304                 hpfs_claim_alloc(s, sec);
306                 return 1;                         305                 return 1;
307         }                                         306         }
308         hpfs_brelse4(&qbh);                       307         hpfs_brelse4(&qbh);
309         end:                                      308         end:
310         return 0;                                 309         return 0;
311 }                                                 310 }
312                                                   311 
313 /* Free sectors in bitmaps */                     312 /* Free sectors in bitmaps */
314                                                   313 
315 void hpfs_free_sectors(struct super_block *s,     314 void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n)
316 {                                                 315 {
317         struct quad_buffer_head qbh;              316         struct quad_buffer_head qbh;
318         __le32 *bmp;                              317         __le32 *bmp;
319         struct hpfs_sb_info *sbi = hpfs_sb(s);    318         struct hpfs_sb_info *sbi = hpfs_sb(s);
320         /*pr_info("2 - ");*/                      319         /*pr_info("2 - ");*/
321         if (!n) return;                           320         if (!n) return;
322         if (sec < 0x12) {                         321         if (sec < 0x12) {
323                 hpfs_error(s, "Trying to free     322                 hpfs_error(s, "Trying to free reserved sector %08x", sec);
324                 return;                           323                 return;
325         }                                         324         }
326         sbi->sb_max_fwd_alloc += n > 0xffff ?     325         sbi->sb_max_fwd_alloc += n > 0xffff ? 0xffff : n;
327         if (sbi->sb_max_fwd_alloc > 0xffffff)     326         if (sbi->sb_max_fwd_alloc > 0xffffff) sbi->sb_max_fwd_alloc = 0xffffff;
328         new_map:                                  327         new_map:
329         if (!(bmp = hpfs_map_bitmap(s, sec >>     328         if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "free"))) {
330                 return;                           329                 return;
331         }                                         330         }       
332         new_tst:                                  331         new_tst:
333         if ((le32_to_cpu(bmp[(sec & 0x3fff) >>    332         if ((le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f) & 1)) {
334                 hpfs_error(s, "sector %08x not    333                 hpfs_error(s, "sector %08x not allocated", sec);
335                 hpfs_brelse4(&qbh);               334                 hpfs_brelse4(&qbh);
336                 return;                           335                 return;
337         }                                         336         }
338         bmp[(sec & 0x3fff) >> 5] |= cpu_to_le3    337         bmp[(sec & 0x3fff) >> 5] |= cpu_to_le32(1 << (sec & 0x1f));
339         hpfs_claim_free(s, sec);                  338         hpfs_claim_free(s, sec);
340         if (!--n) {                               339         if (!--n) {
341                 hpfs_mark_4buffers_dirty(&qbh)    340                 hpfs_mark_4buffers_dirty(&qbh);
342                 hpfs_brelse4(&qbh);               341                 hpfs_brelse4(&qbh);
343                 return;                           342                 return;
344         }                                         343         }       
345         if (!(++sec & 0x3fff)) {                  344         if (!(++sec & 0x3fff)) {
346                 hpfs_mark_4buffers_dirty(&qbh)    345                 hpfs_mark_4buffers_dirty(&qbh);
347                 hpfs_brelse4(&qbh);               346                 hpfs_brelse4(&qbh);
348                 goto new_map;                     347                 goto new_map;
349         }                                         348         }
350         goto new_tst;                             349         goto new_tst;
351 }                                                 350 }
352                                                   351 
353 /*                                                352 /*
354  * Check if there are at least n free dnodes o    353  * Check if there are at least n free dnodes on the filesystem.
355  * Called before adding to dnode. If we run ou    354  * Called before adding to dnode. If we run out of space while
356  * splitting dnodes, it would corrupt dnode tr    355  * splitting dnodes, it would corrupt dnode tree.
357  */                                               356  */
358                                                   357 
359 int hpfs_check_free_dnodes(struct super_block     358 int hpfs_check_free_dnodes(struct super_block *s, int n)
360 {                                                 359 {
361         int n_bmps = (hpfs_sb(s)->sb_fs_size +    360         int n_bmps = (hpfs_sb(s)->sb_fs_size + 0x4000 - 1) >> 14;
362         int b = hpfs_sb(s)->sb_c_bitmap & 0x0f    361         int b = hpfs_sb(s)->sb_c_bitmap & 0x0fffffff;
363         int i, j;                                 362         int i, j;
364         __le32 *bmp;                              363         __le32 *bmp;
365         struct quad_buffer_head qbh;              364         struct quad_buffer_head qbh;
366         if ((bmp = hpfs_map_dnode_bitmap(s, &q    365         if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
367                 for (j = 0; j < 512; j++) {       366                 for (j = 0; j < 512; j++) {
368                         unsigned k;               367                         unsigned k;
369                         if (!le32_to_cpu(bmp[j    368                         if (!le32_to_cpu(bmp[j])) continue;
370                         for (k = le32_to_cpu(b    369                         for (k = le32_to_cpu(bmp[j]); k; k >>= 1) if (k & 1) if (!--n) {
371                                 hpfs_brelse4(&    370                                 hpfs_brelse4(&qbh);
372                                 return 0;         371                                 return 0;
373                         }                         372                         }
374                 }                                 373                 }
375         }                                         374         }
376         hpfs_brelse4(&qbh);                       375         hpfs_brelse4(&qbh);
377         i = 0;                                    376         i = 0;
378         if (hpfs_sb(s)->sb_c_bitmap != -1) {      377         if (hpfs_sb(s)->sb_c_bitmap != -1) {
379                 bmp = hpfs_map_bitmap(s, b, &q    378                 bmp = hpfs_map_bitmap(s, b, &qbh, "chkdn1");
380                 goto chk_bmp;                     379                 goto chk_bmp;
381         }                                         380         }
382         chk_next:                                 381         chk_next:
383         if (i == b) i++;                          382         if (i == b) i++;
384         if (i >= n_bmps) return 1;                383         if (i >= n_bmps) return 1;
385         bmp = hpfs_map_bitmap(s, i, &qbh, "chk    384         bmp = hpfs_map_bitmap(s, i, &qbh, "chkdn2");
386         chk_bmp:                                  385         chk_bmp:
387         if (bmp) {                                386         if (bmp) {
388                 for (j = 0; j < 512; j++) {       387                 for (j = 0; j < 512; j++) {
389                         u32 k;                    388                         u32 k;
390                         if (!le32_to_cpu(bmp[j    389                         if (!le32_to_cpu(bmp[j])) continue;
391                         for (k = 0xf; k; k <<=    390                         for (k = 0xf; k; k <<= 4)
392                                 if ((le32_to_c    391                                 if ((le32_to_cpu(bmp[j]) & k) == k) {
393                                         if (!-    392                                         if (!--n) {
394                                                   393                                                 hpfs_brelse4(&qbh);
395                                                   394                                                 return 0;
396                                         }         395                                         }
397                                 }                 396                                 }
398                 }                                 397                 }
399                 hpfs_brelse4(&qbh);               398                 hpfs_brelse4(&qbh);
400         }                                         399         }
401         i++;                                      400         i++;
402         goto chk_next;                            401         goto chk_next;
403 }                                                 402 }
404                                                   403 
405 void hpfs_free_dnode(struct super_block *s, dn    404 void hpfs_free_dnode(struct super_block *s, dnode_secno dno)
406 {                                                 405 {
407         if (hpfs_sb(s)->sb_chk) if (dno & 3) {    406         if (hpfs_sb(s)->sb_chk) if (dno & 3) {
408                 hpfs_error(s, "hpfs_free_dnode    407                 hpfs_error(s, "hpfs_free_dnode: dnode %08x not aligned", dno);
409                 return;                           408                 return;
410         }                                         409         }
411         if (dno < hpfs_sb(s)->sb_dirband_start    410         if (dno < hpfs_sb(s)->sb_dirband_start ||
412             dno >= hpfs_sb(s)->sb_dirband_star    411             dno >= hpfs_sb(s)->sb_dirband_start + hpfs_sb(s)->sb_dirband_size) {
413                 hpfs_free_sectors(s, dno, 4);     412                 hpfs_free_sectors(s, dno, 4);
414         } else {                                  413         } else {
415                 struct quad_buffer_head qbh;      414                 struct quad_buffer_head qbh;
416                 __le32 *bmp;                      415                 __le32 *bmp;
417                 unsigned ssec = (dno - hpfs_sb    416                 unsigned ssec = (dno - hpfs_sb(s)->sb_dirband_start) / 4;
418                 if (!(bmp = hpfs_map_dnode_bit    417                 if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
419                         return;                   418                         return;
420                 }                                 419                 }
421                 bmp[ssec >> 5] |= cpu_to_le32(    420                 bmp[ssec >> 5] |= cpu_to_le32(1 << (ssec & 0x1f));
422                 hpfs_mark_4buffers_dirty(&qbh)    421                 hpfs_mark_4buffers_dirty(&qbh);
423                 hpfs_brelse4(&qbh);               422                 hpfs_brelse4(&qbh);
424                 hpfs_claim_dirband_free(s, dno    423                 hpfs_claim_dirband_free(s, dno);
425         }                                         424         }
426 }                                                 425 }
427                                                   426 
428 struct dnode *hpfs_alloc_dnode(struct super_bl    427 struct dnode *hpfs_alloc_dnode(struct super_block *s, secno near,
429                          dnode_secno *dno, str    428                          dnode_secno *dno, struct quad_buffer_head *qbh)
430 {                                                 429 {
431         struct dnode *d;                          430         struct dnode *d;
432         if (hpfs_get_free_dnodes(s) > FREE_DNO    431         if (hpfs_get_free_dnodes(s) > FREE_DNODES_ADD) {
433                 if (!(*dno = alloc_in_dirband(    432                 if (!(*dno = alloc_in_dirband(s, near)))
434                         if (!(*dno = hpfs_allo    433                         if (!(*dno = hpfs_alloc_sector(s, near, 4, 0))) return NULL;
435         } else {                                  434         } else {
436                 if (!(*dno = hpfs_alloc_sector    435                 if (!(*dno = hpfs_alloc_sector(s, near, 4, 0)))
437                         if (!(*dno = alloc_in_    436                         if (!(*dno = alloc_in_dirband(s, near))) return NULL;
438         }                                         437         }
439         if (!(d = hpfs_get_4sectors(s, *dno, q    438         if (!(d = hpfs_get_4sectors(s, *dno, qbh))) {
440                 hpfs_free_dnode(s, *dno);         439                 hpfs_free_dnode(s, *dno);
441                 return NULL;                      440                 return NULL;
442         }                                         441         }
443         memset(d, 0, 2048);                       442         memset(d, 0, 2048);
444         d->magic = cpu_to_le32(DNODE_MAGIC);      443         d->magic = cpu_to_le32(DNODE_MAGIC);
445         d->first_free = cpu_to_le32(52);          444         d->first_free = cpu_to_le32(52);
446         d->dirent[0] = 32;                        445         d->dirent[0] = 32;
447         d->dirent[2] = 8;                         446         d->dirent[2] = 8;
448         d->dirent[30] = 1;                        447         d->dirent[30] = 1;
449         d->dirent[31] = 255;                      448         d->dirent[31] = 255;
450         d->self = cpu_to_le32(*dno);              449         d->self = cpu_to_le32(*dno);
451         return d;                                 450         return d;
452 }                                                 451 }
453                                                   452 
454 struct fnode *hpfs_alloc_fnode(struct super_bl    453 struct fnode *hpfs_alloc_fnode(struct super_block *s, secno near, fnode_secno *fno,
455                           struct buffer_head *    454                           struct buffer_head **bh)
456 {                                                 455 {
457         struct fnode *f;                          456         struct fnode *f;
458         if (!(*fno = hpfs_alloc_sector(s, near    457         if (!(*fno = hpfs_alloc_sector(s, near, 1, FNODE_ALLOC_FWD))) return NULL;
459         if (!(f = hpfs_get_sector(s, *fno, bh)    458         if (!(f = hpfs_get_sector(s, *fno, bh))) {
460                 hpfs_free_sectors(s, *fno, 1);    459                 hpfs_free_sectors(s, *fno, 1);
461                 return NULL;                      460                 return NULL;
462         }                                         461         }       
463         memset(f, 0, 512);                        462         memset(f, 0, 512);
464         f->magic = cpu_to_le32(FNODE_MAGIC);      463         f->magic = cpu_to_le32(FNODE_MAGIC);
465         f->ea_offs = cpu_to_le16(0xc4);           464         f->ea_offs = cpu_to_le16(0xc4);
466         f->btree.n_free_nodes = 8;                465         f->btree.n_free_nodes = 8;
467         f->btree.first_free = cpu_to_le16(8);     466         f->btree.first_free = cpu_to_le16(8);
468         return f;                                 467         return f;
469 }                                                 468 }
470                                                   469 
471 struct anode *hpfs_alloc_anode(struct super_bl    470 struct anode *hpfs_alloc_anode(struct super_block *s, secno near, anode_secno *ano,
472                           struct buffer_head *    471                           struct buffer_head **bh)
473 {                                                 472 {
474         struct anode *a;                          473         struct anode *a;
475         if (!(*ano = hpfs_alloc_sector(s, near    474         if (!(*ano = hpfs_alloc_sector(s, near, 1, ANODE_ALLOC_FWD))) return NULL;
476         if (!(a = hpfs_get_sector(s, *ano, bh)    475         if (!(a = hpfs_get_sector(s, *ano, bh))) {
477                 hpfs_free_sectors(s, *ano, 1);    476                 hpfs_free_sectors(s, *ano, 1);
478                 return NULL;                      477                 return NULL;
479         }                                         478         }
480         memset(a, 0, 512);                        479         memset(a, 0, 512);
481         a->magic = cpu_to_le32(ANODE_MAGIC);      480         a->magic = cpu_to_le32(ANODE_MAGIC);
482         a->self = cpu_to_le32(*ano);              481         a->self = cpu_to_le32(*ano);
483         a->btree.n_free_nodes = 40;               482         a->btree.n_free_nodes = 40;
484         a->btree.n_used_nodes = 0;                483         a->btree.n_used_nodes = 0;
485         a->btree.first_free = cpu_to_le16(8);     484         a->btree.first_free = cpu_to_le16(8);
486         return a;                                 485         return a;
487 }                                                 486 }
488                                                   487 
489 static unsigned find_run(__le32 *bmp, unsigned    488 static unsigned find_run(__le32 *bmp, unsigned *idx)
490 {                                                 489 {
491         unsigned len;                             490         unsigned len;
492         while (tstbits(bmp, *idx, 1)) {           491         while (tstbits(bmp, *idx, 1)) {
493                 (*idx)++;                         492                 (*idx)++;
494                 if (unlikely(*idx >= 0x4000))     493                 if (unlikely(*idx >= 0x4000))
495                         return 0;                 494                         return 0;
496         }                                         495         }
497         len = 1;                                  496         len = 1;
498         while (!tstbits(bmp, *idx + len, 1))      497         while (!tstbits(bmp, *idx + len, 1))
499                 len++;                            498                 len++;
500         return len;                               499         return len;
501 }                                                 500 }
502                                                   501 
503 static int do_trim(struct super_block *s, secn    502 static int do_trim(struct super_block *s, secno start, unsigned len, secno limit_start, secno limit_end, unsigned minlen, unsigned *result)
504 {                                                 503 {
505         int err;                                  504         int err;
506         secno end;                                505         secno end;
507         if (fatal_signal_pending(current))        506         if (fatal_signal_pending(current))
508                 return -EINTR;                    507                 return -EINTR;
509         end = start + len;                        508         end = start + len;
510         if (start < limit_start)                  509         if (start < limit_start)
511                 start = limit_start;              510                 start = limit_start;
512         if (end > limit_end)                      511         if (end > limit_end)
513                 end = limit_end;                  512                 end = limit_end;
514         if (start >= end)                         513         if (start >= end)
515                 return 0;                         514                 return 0;
516         if (end - start < minlen)                 515         if (end - start < minlen)
517                 return 0;                         516                 return 0;
518         err = sb_issue_discard(s, start, end -    517         err = sb_issue_discard(s, start, end - start, GFP_NOFS, 0);
519         if (err)                                  518         if (err)
520                 return err;                       519                 return err;
521         *result += end - start;                   520         *result += end - start;
522         return 0;                                 521         return 0;
523 }                                                 522 }
524                                                   523 
525 int hpfs_trim_fs(struct super_block *s, u64 st    524 int hpfs_trim_fs(struct super_block *s, u64 start, u64 end, u64 minlen, unsigned *result)
526 {                                                 525 {
527         int err = 0;                              526         int err = 0;
528         struct hpfs_sb_info *sbi = hpfs_sb(s);    527         struct hpfs_sb_info *sbi = hpfs_sb(s);
529         unsigned idx, len, start_bmp, end_bmp;    528         unsigned idx, len, start_bmp, end_bmp;
530         __le32 *bmp;                              529         __le32 *bmp;
531         struct quad_buffer_head qbh;              530         struct quad_buffer_head qbh;
532                                                   531 
533         *result = 0;                              532         *result = 0;
534         if (!end || end > sbi->sb_fs_size)        533         if (!end || end > sbi->sb_fs_size)
535                 end = sbi->sb_fs_size;            534                 end = sbi->sb_fs_size;
536         if (start >= sbi->sb_fs_size)             535         if (start >= sbi->sb_fs_size)
537                 return 0;                         536                 return 0;
538         if (minlen > 0x4000)                      537         if (minlen > 0x4000)
539                 return 0;                         538                 return 0;
540         if (start < sbi->sb_dirband_start + sb    539         if (start < sbi->sb_dirband_start + sbi->sb_dirband_size && end > sbi->sb_dirband_start) {
541                 hpfs_lock(s);                     540                 hpfs_lock(s);
542                 if (sb_rdonly(s)) {            !! 541                 if (s->s_flags & MS_RDONLY) {
543                         err = -EROFS;             542                         err = -EROFS;
544                         goto unlock_1;            543                         goto unlock_1;
545                 }                                 544                 }
546                 if (!(bmp = hpfs_map_dnode_bit    545                 if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
547                         err = -EIO;               546                         err = -EIO;
548                         goto unlock_1;            547                         goto unlock_1;
549                 }                                 548                 }
550                 idx = 0;                          549                 idx = 0;
551                 while ((len = find_run(bmp, &i    550                 while ((len = find_run(bmp, &idx)) && !err) {
552                         err = do_trim(s, sbi->    551                         err = do_trim(s, sbi->sb_dirband_start + idx * 4, len * 4, start, end, minlen, result);
553                         idx += len;               552                         idx += len;
554                 }                                 553                 }
555                 hpfs_brelse4(&qbh);               554                 hpfs_brelse4(&qbh);
556 unlock_1:                                         555 unlock_1:
557                 hpfs_unlock(s);                   556                 hpfs_unlock(s);
558         }                                         557         }
559         start_bmp = start >> 14;                  558         start_bmp = start >> 14;
560         end_bmp = (end + 0x3fff) >> 14;           559         end_bmp = (end + 0x3fff) >> 14;
561         while (start_bmp < end_bmp && !err) {     560         while (start_bmp < end_bmp && !err) {
562                 hpfs_lock(s);                     561                 hpfs_lock(s);
563                 if (sb_rdonly(s)) {            !! 562                 if (s->s_flags & MS_RDONLY) {
564                         err = -EROFS;             563                         err = -EROFS;
565                         goto unlock_2;            564                         goto unlock_2;
566                 }                                 565                 }
567                 if (!(bmp = hpfs_map_bitmap(s,    566                 if (!(bmp = hpfs_map_bitmap(s, start_bmp, &qbh, "trim"))) {
568                         err = -EIO;               567                         err = -EIO;
569                         goto unlock_2;            568                         goto unlock_2;
570                 }                                 569                 }
571                 idx = 0;                          570                 idx = 0;
572                 while ((len = find_run(bmp, &i    571                 while ((len = find_run(bmp, &idx)) && !err) {
573                         err = do_trim(s, (star    572                         err = do_trim(s, (start_bmp << 14) + idx, len, start, end, minlen, result);
574                         idx += len;               573                         idx += len;
575                 }                                 574                 }
576                 hpfs_brelse4(&qbh);               575                 hpfs_brelse4(&qbh);
577 unlock_2:                                         576 unlock_2:
578                 hpfs_unlock(s);                   577                 hpfs_unlock(s);
579                 start_bmp++;                      578                 start_bmp++;
580         }                                         579         }
581         return err;                               580         return err;
582 }                                                 581 }
583                                                   582 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php