• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
4  */
5 
6 #include <linux/buffer_head.h>
7 #include <linux/fs.h>
8 #include <linux/mutex.h>
9 #include "exfat.h"
10 
11 #define LOCKBIT		0x01
12 #define DIRTYBIT	0x02
13 
14 /* Local variables */
15 static DEFINE_SEMAPHORE(f_sem);
16 static DEFINE_SEMAPHORE(b_sem);
17 
FAT_cache_find(struct super_block * sb,sector_t sec)18 static struct buf_cache_t *FAT_cache_find(struct super_block *sb, sector_t sec)
19 {
20 	s32 off;
21 	struct buf_cache_t *bp, *hp;
22 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
23 
24 	off = (sec +
25 	       (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1);
26 
27 	hp = &p_fs->FAT_cache_hash_list[off];
28 	for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
29 		if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
30 			WARN(!bp->buf_bh,
31 			     "[EXFAT] FAT_cache has no bh. It will make system panic.\n");
32 
33 			touch_buffer(bp->buf_bh);
34 			return bp;
35 		}
36 	}
37 	return NULL;
38 }
39 
push_to_mru(struct buf_cache_t * bp,struct buf_cache_t * list)40 static void push_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list)
41 {
42 	bp->next = list->next;
43 	bp->prev = list;
44 	list->next->prev = bp;
45 	list->next = bp;
46 }
47 
push_to_lru(struct buf_cache_t * bp,struct buf_cache_t * list)48 static void push_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list)
49 {
50 	bp->prev = list->prev;
51 	bp->next = list;
52 	list->prev->next = bp;
53 	list->prev = bp;
54 }
55 
move_to_mru(struct buf_cache_t * bp,struct buf_cache_t * list)56 static void move_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list)
57 {
58 	bp->prev->next = bp->next;
59 	bp->next->prev = bp->prev;
60 	push_to_mru(bp, list);
61 }
62 
move_to_lru(struct buf_cache_t * bp,struct buf_cache_t * list)63 static void move_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list)
64 {
65 	bp->prev->next = bp->next;
66 	bp->next->prev = bp->prev;
67 	push_to_lru(bp, list);
68 }
69 
FAT_cache_get(struct super_block * sb,sector_t sec)70 static struct buf_cache_t *FAT_cache_get(struct super_block *sb, sector_t sec)
71 {
72 	struct buf_cache_t *bp;
73 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
74 
75 	bp = p_fs->FAT_cache_lru_list.prev;
76 
77 	move_to_mru(bp, &p_fs->FAT_cache_lru_list);
78 	return bp;
79 }
80 
FAT_cache_insert_hash(struct super_block * sb,struct buf_cache_t * bp)81 static void FAT_cache_insert_hash(struct super_block *sb,
82 				  struct buf_cache_t *bp)
83 {
84 	s32 off;
85 	struct buf_cache_t *hp;
86 	struct fs_info_t *p_fs;
87 
88 	p_fs = &(EXFAT_SB(sb)->fs_info);
89 	off = (bp->sec +
90 	       (bp->sec >> p_fs->sectors_per_clu_bits)) &
91 		(FAT_CACHE_HASH_SIZE - 1);
92 
93 	hp = &p_fs->FAT_cache_hash_list[off];
94 	bp->hash_next = hp->hash_next;
95 	bp->hash_prev = hp;
96 	hp->hash_next->hash_prev = bp;
97 	hp->hash_next = bp;
98 }
99 
FAT_cache_remove_hash(struct buf_cache_t * bp)100 static void FAT_cache_remove_hash(struct buf_cache_t *bp)
101 {
102 	(bp->hash_prev)->hash_next = bp->hash_next;
103 	(bp->hash_next)->hash_prev = bp->hash_prev;
104 }
105 
buf_cache_insert_hash(struct super_block * sb,struct buf_cache_t * bp)106 static void buf_cache_insert_hash(struct super_block *sb,
107 				  struct buf_cache_t *bp)
108 {
109 	s32 off;
110 	struct buf_cache_t *hp;
111 	struct fs_info_t *p_fs;
112 
113 	p_fs = &(EXFAT_SB(sb)->fs_info);
114 	off = (bp->sec +
115 	       (bp->sec >> p_fs->sectors_per_clu_bits)) &
116 		(BUF_CACHE_HASH_SIZE - 1);
117 
118 	hp = &p_fs->buf_cache_hash_list[off];
119 	bp->hash_next = hp->hash_next;
120 	bp->hash_prev = hp;
121 	hp->hash_next->hash_prev = bp;
122 	hp->hash_next = bp;
123 }
124 
buf_cache_remove_hash(struct buf_cache_t * bp)125 static void buf_cache_remove_hash(struct buf_cache_t *bp)
126 {
127 	(bp->hash_prev)->hash_next = bp->hash_next;
128 	(bp->hash_next)->hash_prev = bp->hash_prev;
129 }
130 
buf_init(struct super_block * sb)131 void buf_init(struct super_block *sb)
132 {
133 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
134 
135 	int i;
136 
137 	/* LRU list */
138 	p_fs->FAT_cache_lru_list.next = &p_fs->FAT_cache_lru_list;
139 	p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list;
140 
141 	for (i = 0; i < FAT_CACHE_SIZE; i++) {
142 		p_fs->FAT_cache_array[i].drv = -1;
143 		p_fs->FAT_cache_array[i].sec = ~0;
144 		p_fs->FAT_cache_array[i].flag = 0;
145 		p_fs->FAT_cache_array[i].buf_bh = NULL;
146 		p_fs->FAT_cache_array[i].prev = NULL;
147 		p_fs->FAT_cache_array[i].next = NULL;
148 		push_to_mru(&p_fs->FAT_cache_array[i],
149 			    &p_fs->FAT_cache_lru_list);
150 	}
151 
152 	p_fs->buf_cache_lru_list.next = &p_fs->buf_cache_lru_list;
153 	p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list;
154 
155 	for (i = 0; i < BUF_CACHE_SIZE; i++) {
156 		p_fs->buf_cache_array[i].drv = -1;
157 		p_fs->buf_cache_array[i].sec = ~0;
158 		p_fs->buf_cache_array[i].flag = 0;
159 		p_fs->buf_cache_array[i].buf_bh = NULL;
160 		p_fs->buf_cache_array[i].prev = NULL;
161 		p_fs->buf_cache_array[i].next = NULL;
162 		push_to_mru(&p_fs->buf_cache_array[i],
163 			    &p_fs->buf_cache_lru_list);
164 	}
165 
166 	/* HASH list */
167 	for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) {
168 		p_fs->FAT_cache_hash_list[i].drv = -1;
169 		p_fs->FAT_cache_hash_list[i].sec = ~0;
170 		p_fs->FAT_cache_hash_list[i].hash_next =
171 			&p_fs->FAT_cache_hash_list[i];
172 		p_fs->FAT_cache_hash_list[i].hash_prev =
173 			&p_fs->FAT_cache_hash_list[i];
174 	}
175 
176 	for (i = 0; i < FAT_CACHE_SIZE; i++)
177 		FAT_cache_insert_hash(sb, &p_fs->FAT_cache_array[i]);
178 
179 	for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) {
180 		p_fs->buf_cache_hash_list[i].drv = -1;
181 		p_fs->buf_cache_hash_list[i].sec = ~0;
182 		p_fs->buf_cache_hash_list[i].hash_next =
183 			&p_fs->buf_cache_hash_list[i];
184 		p_fs->buf_cache_hash_list[i].hash_prev =
185 			&p_fs->buf_cache_hash_list[i];
186 	}
187 
188 	for (i = 0; i < BUF_CACHE_SIZE; i++)
189 		buf_cache_insert_hash(sb, &p_fs->buf_cache_array[i]);
190 }
191 
buf_shutdown(struct super_block * sb)192 void buf_shutdown(struct super_block *sb)
193 {
194 }
195 
__FAT_read(struct super_block * sb,u32 loc,u32 * content)196 static int __FAT_read(struct super_block *sb, u32 loc, u32 *content)
197 {
198 	s32 off;
199 	u32 _content;
200 	sector_t sec;
201 	u8 *fat_sector, *fat_entry;
202 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
203 	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
204 
205 	if (p_fs->vol_type == FAT12) {
206 		sec = p_fs->FAT1_start_sector +
207 			((loc + (loc >> 1)) >> p_bd->sector_size_bits);
208 		off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
209 
210 		if (off == (p_bd->sector_size - 1)) {
211 			fat_sector = FAT_getblk(sb, sec);
212 			if (!fat_sector)
213 				return -1;
214 
215 			_content = (u32)fat_sector[off];
216 
217 			fat_sector = FAT_getblk(sb, ++sec);
218 			if (!fat_sector)
219 				return -1;
220 
221 			_content |= (u32)fat_sector[0] << 8;
222 		} else {
223 			fat_sector = FAT_getblk(sb, sec);
224 			if (!fat_sector)
225 				return -1;
226 
227 			fat_entry = &fat_sector[off];
228 			_content = GET16(fat_entry);
229 		}
230 
231 		if (loc & 1)
232 			_content >>= 4;
233 
234 		_content &= 0x00000FFF;
235 
236 		if (_content >= CLUSTER_16(0x0FF8)) {
237 			*content = CLUSTER_32(~0);
238 			return 0;
239 		}
240 		*content = CLUSTER_32(_content);
241 		return 0;
242 	} else if (p_fs->vol_type == FAT16) {
243 		sec = p_fs->FAT1_start_sector +
244 			(loc >> (p_bd->sector_size_bits - 1));
245 		off = (loc << 1) & p_bd->sector_size_mask;
246 
247 		fat_sector = FAT_getblk(sb, sec);
248 		if (!fat_sector)
249 			return -1;
250 
251 		fat_entry = &fat_sector[off];
252 
253 		_content = GET16_A(fat_entry);
254 
255 		_content &= 0x0000FFFF;
256 
257 		if (_content >= CLUSTER_16(0xFFF8)) {
258 			*content = CLUSTER_32(~0);
259 			return 0;
260 		}
261 		*content = CLUSTER_32(_content);
262 		return 0;
263 	} else if (p_fs->vol_type == FAT32) {
264 		sec = p_fs->FAT1_start_sector +
265 			(loc >> (p_bd->sector_size_bits - 2));
266 		off = (loc << 2) & p_bd->sector_size_mask;
267 
268 		fat_sector = FAT_getblk(sb, sec);
269 		if (!fat_sector)
270 			return -1;
271 
272 		fat_entry = &fat_sector[off];
273 
274 		_content = GET32_A(fat_entry);
275 
276 		_content &= 0x0FFFFFFF;
277 
278 		if (_content >= CLUSTER_32(0x0FFFFFF8)) {
279 			*content = CLUSTER_32(~0);
280 			return 0;
281 		}
282 		*content = CLUSTER_32(_content);
283 		return 0;
284 	} else if (p_fs->vol_type == EXFAT) {
285 		sec = p_fs->FAT1_start_sector +
286 			(loc >> (p_bd->sector_size_bits - 2));
287 		off = (loc << 2) & p_bd->sector_size_mask;
288 
289 		fat_sector = FAT_getblk(sb, sec);
290 		if (!fat_sector)
291 			return -1;
292 
293 		fat_entry = &fat_sector[off];
294 		_content = GET32_A(fat_entry);
295 
296 		if (_content >= CLUSTER_32(0xFFFFFFF8)) {
297 			*content = CLUSTER_32(~0);
298 			return 0;
299 		}
300 		*content = CLUSTER_32(_content);
301 		return 0;
302 	}
303 
304 	/* Unknown volume type, throw in the towel and go home */
305 	*content = CLUSTER_32(~0);
306 	return 0;
307 }
308 
309 /* in : sb, loc
310  * out: content
311  * returns 0 on success
312  *            -1 on error
313  */
FAT_read(struct super_block * sb,u32 loc,u32 * content)314 int FAT_read(struct super_block *sb, u32 loc, u32 *content)
315 {
316 	s32 ret;
317 
318 	down(&f_sem);
319 	ret = __FAT_read(sb, loc, content);
320 	up(&f_sem);
321 
322 	return ret;
323 }
324 
__FAT_write(struct super_block * sb,u32 loc,u32 content)325 static s32 __FAT_write(struct super_block *sb, u32 loc, u32 content)
326 {
327 	s32 off;
328 	sector_t sec;
329 	u8 *fat_sector, *fat_entry;
330 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
331 	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
332 
333 	if (p_fs->vol_type == FAT12) {
334 		content &= 0x00000FFF;
335 
336 		sec = p_fs->FAT1_start_sector +
337 			((loc + (loc >> 1)) >> p_bd->sector_size_bits);
338 		off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
339 
340 		fat_sector = FAT_getblk(sb, sec);
341 		if (!fat_sector)
342 			return -1;
343 
344 		if (loc & 1) { /* odd */
345 			content <<= 4;
346 
347 			if (off == (p_bd->sector_size - 1)) {
348 				fat_sector[off] = (u8)(content |
349 						       (fat_sector[off] &
350 							0x0F));
351 				FAT_modify(sb, sec);
352 
353 				fat_sector = FAT_getblk(sb, ++sec);
354 				if (!fat_sector)
355 					return -1;
356 
357 				fat_sector[0] = (u8)(content >> 8);
358 			} else {
359 				fat_entry = &fat_sector[off];
360 				content |= GET16(fat_entry) & 0x000F;
361 
362 				SET16(fat_entry, content);
363 			}
364 		} else { /* even */
365 			fat_sector[off] = (u8)(content);
366 
367 			if (off == (p_bd->sector_size - 1)) {
368 				fat_sector[off] = (u8)(content);
369 				FAT_modify(sb, sec);
370 
371 				fat_sector = FAT_getblk(sb, ++sec);
372 				if (!fat_sector)
373 					return -1;
374 				fat_sector[0] = (u8)((fat_sector[0] & 0xF0) |
375 						     (content >> 8));
376 			} else {
377 				fat_entry = &fat_sector[off];
378 				content |= GET16(fat_entry) & 0xF000;
379 
380 				SET16(fat_entry, content);
381 			}
382 		}
383 	}
384 
385 	else if (p_fs->vol_type == FAT16) {
386 		content &= 0x0000FFFF;
387 
388 		sec = p_fs->FAT1_start_sector + (loc >>
389 						 (p_bd->sector_size_bits - 1));
390 		off = (loc << 1) & p_bd->sector_size_mask;
391 
392 		fat_sector = FAT_getblk(sb, sec);
393 		if (!fat_sector)
394 			return -1;
395 
396 		fat_entry = &fat_sector[off];
397 
398 		SET16_A(fat_entry, content);
399 	} else if (p_fs->vol_type == FAT32) {
400 		content &= 0x0FFFFFFF;
401 
402 		sec = p_fs->FAT1_start_sector + (loc >>
403 						 (p_bd->sector_size_bits - 2));
404 		off = (loc << 2) & p_bd->sector_size_mask;
405 
406 		fat_sector = FAT_getblk(sb, sec);
407 		if (!fat_sector)
408 			return -1;
409 
410 		fat_entry = &fat_sector[off];
411 
412 		content |= GET32_A(fat_entry) & 0xF0000000;
413 
414 		SET32_A(fat_entry, content);
415 	} else { /* p_fs->vol_type == EXFAT */
416 		sec = p_fs->FAT1_start_sector + (loc >>
417 						 (p_bd->sector_size_bits - 2));
418 		off = (loc << 2) & p_bd->sector_size_mask;
419 
420 		fat_sector = FAT_getblk(sb, sec);
421 		if (!fat_sector)
422 			return -1;
423 
424 		fat_entry = &fat_sector[off];
425 
426 		SET32_A(fat_entry, content);
427 	}
428 
429 	FAT_modify(sb, sec);
430 	return 0;
431 }
432 
FAT_write(struct super_block * sb,u32 loc,u32 content)433 int FAT_write(struct super_block *sb, u32 loc, u32 content)
434 {
435 	s32 ret;
436 
437 	down(&f_sem);
438 	ret = __FAT_write(sb, loc, content);
439 	up(&f_sem);
440 
441 	return ret;
442 }
443 
FAT_getblk(struct super_block * sb,sector_t sec)444 u8 *FAT_getblk(struct super_block *sb, sector_t sec)
445 {
446 	struct buf_cache_t *bp;
447 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
448 
449 	bp = FAT_cache_find(sb, sec);
450 	if (bp) {
451 		move_to_mru(bp, &p_fs->FAT_cache_lru_list);
452 		return bp->buf_bh->b_data;
453 	}
454 
455 	bp = FAT_cache_get(sb, sec);
456 
457 	FAT_cache_remove_hash(bp);
458 
459 	bp->drv = p_fs->drv;
460 	bp->sec = sec;
461 	bp->flag = 0;
462 
463 	FAT_cache_insert_hash(sb, bp);
464 
465 	if (sector_read(sb, sec, &bp->buf_bh, 1) != FFS_SUCCESS) {
466 		FAT_cache_remove_hash(bp);
467 		bp->drv = -1;
468 		bp->sec = ~0;
469 		bp->flag = 0;
470 		bp->buf_bh = NULL;
471 
472 		move_to_lru(bp, &p_fs->FAT_cache_lru_list);
473 		return NULL;
474 	}
475 
476 	return bp->buf_bh->b_data;
477 }
478 
FAT_modify(struct super_block * sb,sector_t sec)479 void FAT_modify(struct super_block *sb, sector_t sec)
480 {
481 	struct buf_cache_t *bp;
482 
483 	bp = FAT_cache_find(sb, sec);
484 	if (bp)
485 		sector_write(sb, sec, bp->buf_bh, 0);
486 }
487 
FAT_release_all(struct super_block * sb)488 void FAT_release_all(struct super_block *sb)
489 {
490 	struct buf_cache_t *bp;
491 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
492 
493 	down(&f_sem);
494 
495 	bp = p_fs->FAT_cache_lru_list.next;
496 	while (bp != &p_fs->FAT_cache_lru_list) {
497 		if (bp->drv == p_fs->drv) {
498 			bp->drv = -1;
499 			bp->sec = ~0;
500 			bp->flag = 0;
501 
502 			if (bp->buf_bh) {
503 				__brelse(bp->buf_bh);
504 				bp->buf_bh = NULL;
505 			}
506 		}
507 		bp = bp->next;
508 	}
509 
510 	up(&f_sem);
511 }
512 
FAT_sync(struct super_block * sb)513 void FAT_sync(struct super_block *sb)
514 {
515 	struct buf_cache_t *bp;
516 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
517 
518 	down(&f_sem);
519 
520 	bp = p_fs->FAT_cache_lru_list.next;
521 	while (bp != &p_fs->FAT_cache_lru_list) {
522 		if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
523 			sync_dirty_buffer(bp->buf_bh);
524 			bp->flag &= ~(DIRTYBIT);
525 		}
526 		bp = bp->next;
527 	}
528 
529 	up(&f_sem);
530 }
531 
buf_cache_find(struct super_block * sb,sector_t sec)532 static struct buf_cache_t *buf_cache_find(struct super_block *sb, sector_t sec)
533 {
534 	s32 off;
535 	struct buf_cache_t *bp, *hp;
536 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
537 
538 	off = (sec + (sec >> p_fs->sectors_per_clu_bits)) &
539 		(BUF_CACHE_HASH_SIZE - 1);
540 
541 	hp = &p_fs->buf_cache_hash_list[off];
542 	for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
543 		if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
544 			touch_buffer(bp->buf_bh);
545 			return bp;
546 		}
547 	}
548 	return NULL;
549 }
550 
buf_cache_get(struct super_block * sb,sector_t sec)551 static struct buf_cache_t *buf_cache_get(struct super_block *sb, sector_t sec)
552 {
553 	struct buf_cache_t *bp;
554 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
555 
556 	bp = p_fs->buf_cache_lru_list.prev;
557 	while (bp->flag & LOCKBIT)
558 		bp = bp->prev;
559 
560 	move_to_mru(bp, &p_fs->buf_cache_lru_list);
561 	return bp;
562 }
563 
__buf_getblk(struct super_block * sb,sector_t sec)564 static u8 *__buf_getblk(struct super_block *sb, sector_t sec)
565 {
566 	struct buf_cache_t *bp;
567 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
568 
569 	bp = buf_cache_find(sb, sec);
570 	if (bp) {
571 		move_to_mru(bp, &p_fs->buf_cache_lru_list);
572 		return bp->buf_bh->b_data;
573 	}
574 
575 	bp = buf_cache_get(sb, sec);
576 
577 	buf_cache_remove_hash(bp);
578 
579 	bp->drv = p_fs->drv;
580 	bp->sec = sec;
581 	bp->flag = 0;
582 
583 	buf_cache_insert_hash(sb, bp);
584 
585 	if (sector_read(sb, sec, &bp->buf_bh, 1) != FFS_SUCCESS) {
586 		buf_cache_remove_hash(bp);
587 		bp->drv = -1;
588 		bp->sec = ~0;
589 		bp->flag = 0;
590 		bp->buf_bh = NULL;
591 
592 		move_to_lru(bp, &p_fs->buf_cache_lru_list);
593 		return NULL;
594 	}
595 
596 	return bp->buf_bh->b_data;
597 }
598 
buf_getblk(struct super_block * sb,sector_t sec)599 u8 *buf_getblk(struct super_block *sb, sector_t sec)
600 {
601 	u8 *buf;
602 
603 	down(&b_sem);
604 	buf = __buf_getblk(sb, sec);
605 	up(&b_sem);
606 
607 	return buf;
608 }
609 
buf_modify(struct super_block * sb,sector_t sec)610 void buf_modify(struct super_block *sb, sector_t sec)
611 {
612 	struct buf_cache_t *bp;
613 
614 	down(&b_sem);
615 
616 	bp = buf_cache_find(sb, sec);
617 	if (likely(bp))
618 		sector_write(sb, sec, bp->buf_bh, 0);
619 
620 	WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n",
621 	     (unsigned long long)sec);
622 
623 	up(&b_sem);
624 }
625 
buf_lock(struct super_block * sb,sector_t sec)626 void buf_lock(struct super_block *sb, sector_t sec)
627 {
628 	struct buf_cache_t *bp;
629 
630 	down(&b_sem);
631 
632 	bp = buf_cache_find(sb, sec);
633 	if (likely(bp))
634 		bp->flag |= LOCKBIT;
635 
636 	WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n",
637 	     (unsigned long long)sec);
638 
639 	up(&b_sem);
640 }
641 
buf_unlock(struct super_block * sb,sector_t sec)642 void buf_unlock(struct super_block *sb, sector_t sec)
643 {
644 	struct buf_cache_t *bp;
645 
646 	down(&b_sem);
647 
648 	bp = buf_cache_find(sb, sec);
649 	if (likely(bp))
650 		bp->flag &= ~(LOCKBIT);
651 
652 	WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n",
653 	     (unsigned long long)sec);
654 
655 	up(&b_sem);
656 }
657 
buf_release(struct super_block * sb,sector_t sec)658 void buf_release(struct super_block *sb, sector_t sec)
659 {
660 	struct buf_cache_t *bp;
661 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
662 
663 	down(&b_sem);
664 
665 	bp = buf_cache_find(sb, sec);
666 	if (likely(bp)) {
667 		bp->drv = -1;
668 		bp->sec = ~0;
669 		bp->flag = 0;
670 
671 		if (bp->buf_bh) {
672 			__brelse(bp->buf_bh);
673 			bp->buf_bh = NULL;
674 		}
675 
676 		move_to_lru(bp, &p_fs->buf_cache_lru_list);
677 	}
678 
679 	up(&b_sem);
680 }
681 
buf_release_all(struct super_block * sb)682 void buf_release_all(struct super_block *sb)
683 {
684 	struct buf_cache_t *bp;
685 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
686 
687 	down(&b_sem);
688 
689 	bp = p_fs->buf_cache_lru_list.next;
690 	while (bp != &p_fs->buf_cache_lru_list) {
691 		if (bp->drv == p_fs->drv) {
692 			bp->drv = -1;
693 			bp->sec = ~0;
694 			bp->flag = 0;
695 
696 			if (bp->buf_bh) {
697 				__brelse(bp->buf_bh);
698 				bp->buf_bh = NULL;
699 			}
700 		}
701 		bp = bp->next;
702 	}
703 
704 	up(&b_sem);
705 }
706 
buf_sync(struct super_block * sb)707 void buf_sync(struct super_block *sb)
708 {
709 	struct buf_cache_t *bp;
710 	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
711 
712 	down(&b_sem);
713 
714 	bp = p_fs->buf_cache_lru_list.next;
715 	while (bp != &p_fs->buf_cache_lru_list) {
716 		if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
717 			sync_dirty_buffer(bp->buf_bh);
718 			bp->flag &= ~(DIRTYBIT);
719 		}
720 		bp = bp->next;
721 	}
722 
723 	up(&b_sem);
724 }
725