Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  linux/fs/hpfs/buffer.c
0004  *
0005  *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
0006  *
0007  *  general buffer i/o
0008  */
0009 #include <linux/sched.h>
0010 #include <linux/slab.h>
0011 #include <linux/blkdev.h>
0012 #include "hpfs_fn.h"
0013 
0014 secno hpfs_search_hotfix_map(struct super_block *s, secno sec)
0015 {
0016     unsigned i;
0017     struct hpfs_sb_info *sbi = hpfs_sb(s);
0018     for (i = 0; unlikely(i < sbi->n_hotfixes); i++) {
0019         if (sbi->hotfix_from[i] == sec) {
0020             return sbi->hotfix_to[i];
0021         }
0022     }
0023     return sec;
0024 }
0025 
0026 unsigned hpfs_search_hotfix_map_for_range(struct super_block *s, secno sec, unsigned n)
0027 {
0028     unsigned i;
0029     struct hpfs_sb_info *sbi = hpfs_sb(s);
0030     for (i = 0; unlikely(i < sbi->n_hotfixes); i++) {
0031         if (sbi->hotfix_from[i] >= sec && sbi->hotfix_from[i] < sec + n) {
0032             n = sbi->hotfix_from[i] - sec;
0033         }
0034     }
0035     return n;
0036 }
0037 
0038 void hpfs_prefetch_sectors(struct super_block *s, unsigned secno, int n)
0039 {
0040     struct buffer_head *bh;
0041     struct blk_plug plug;
0042 
0043     if (n <= 0 || unlikely(secno >= hpfs_sb(s)->sb_fs_size))
0044         return;
0045 
0046     if (unlikely(hpfs_search_hotfix_map_for_range(s, secno, n) != n))
0047         return;
0048 
0049     bh = sb_find_get_block(s, secno);
0050     if (bh) {
0051         if (buffer_uptodate(bh)) {
0052             brelse(bh);
0053             return;
0054         }
0055         brelse(bh);
0056     }
0057 
0058     blk_start_plug(&plug);
0059     while (n > 0) {
0060         if (unlikely(secno >= hpfs_sb(s)->sb_fs_size))
0061             break;
0062         sb_breadahead(s, secno);
0063         secno++;
0064         n--;
0065     }
0066     blk_finish_plug(&plug);
0067 }
0068 
0069 /* Map a sector into a buffer and return pointers to it and to the buffer. */
0070 
0071 void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp,
0072          int ahead)
0073 {
0074     struct buffer_head *bh;
0075 
0076     hpfs_lock_assert(s);
0077 
0078     hpfs_prefetch_sectors(s, secno, ahead);
0079 
0080     cond_resched();
0081 
0082     *bhp = bh = sb_bread(s, hpfs_search_hotfix_map(s, secno));
0083     if (bh != NULL)
0084         return bh->b_data;
0085     else {
0086         pr_err("%s(): read error\n", __func__);
0087         return NULL;
0088     }
0089 }
0090 
0091 /* Like hpfs_map_sector but don't read anything */
0092 
0093 void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp)
0094 {
0095     struct buffer_head *bh;
0096     /*return hpfs_map_sector(s, secno, bhp, 0);*/
0097 
0098     hpfs_lock_assert(s);
0099 
0100     cond_resched();
0101 
0102     if ((*bhp = bh = sb_getblk(s, hpfs_search_hotfix_map(s, secno))) != NULL) {
0103         if (!buffer_uptodate(bh)) wait_on_buffer(bh);
0104         set_buffer_uptodate(bh);
0105         return bh->b_data;
0106     } else {
0107         pr_err("%s(): getblk failed\n", __func__);
0108         return NULL;
0109     }
0110 }
0111 
0112 /* Map 4 sectors into a 4buffer and return pointers to it and to the buffer. */
0113 
0114 void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh,
0115            int ahead)
0116 {
0117     char *data;
0118 
0119     hpfs_lock_assert(s);
0120 
0121     cond_resched();
0122 
0123     if (secno & 3) {
0124         pr_err("%s(): unaligned read\n", __func__);
0125         return NULL;
0126     }
0127 
0128     hpfs_prefetch_sectors(s, secno, 4 + ahead);
0129 
0130     if (!hpfs_map_sector(s, secno + 0, &qbh->bh[0], 0)) goto bail0;
0131     if (!hpfs_map_sector(s, secno + 1, &qbh->bh[1], 0)) goto bail1;
0132     if (!hpfs_map_sector(s, secno + 2, &qbh->bh[2], 0)) goto bail2;
0133     if (!hpfs_map_sector(s, secno + 3, &qbh->bh[3], 0)) goto bail3;
0134 
0135     if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) &&
0136         likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) &&
0137         likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) {
0138         return qbh->data = qbh->bh[0]->b_data;
0139     }
0140 
0141     qbh->data = data = kmalloc(2048, GFP_NOFS);
0142     if (!data) {
0143         pr_err("%s(): out of memory\n", __func__);
0144         goto bail4;
0145     }
0146 
0147     memcpy(data + 0 * 512, qbh->bh[0]->b_data, 512);
0148     memcpy(data + 1 * 512, qbh->bh[1]->b_data, 512);
0149     memcpy(data + 2 * 512, qbh->bh[2]->b_data, 512);
0150     memcpy(data + 3 * 512, qbh->bh[3]->b_data, 512);
0151 
0152     return data;
0153 
0154  bail4:
0155     brelse(qbh->bh[3]);
0156  bail3:
0157     brelse(qbh->bh[2]);
0158  bail2:
0159     brelse(qbh->bh[1]);
0160  bail1:
0161     brelse(qbh->bh[0]);
0162  bail0:
0163     return NULL;
0164 }
0165 
0166 /* Don't read sectors */
0167 
0168 void *hpfs_get_4sectors(struct super_block *s, unsigned secno,
0169                           struct quad_buffer_head *qbh)
0170 {
0171     cond_resched();
0172 
0173     hpfs_lock_assert(s);
0174 
0175     if (secno & 3) {
0176         pr_err("%s(): unaligned read\n", __func__);
0177         return NULL;
0178     }
0179 
0180     if (!hpfs_get_sector(s, secno + 0, &qbh->bh[0])) goto bail0;
0181     if (!hpfs_get_sector(s, secno + 1, &qbh->bh[1])) goto bail1;
0182     if (!hpfs_get_sector(s, secno + 2, &qbh->bh[2])) goto bail2;
0183     if (!hpfs_get_sector(s, secno + 3, &qbh->bh[3])) goto bail3;
0184 
0185     if (likely(qbh->bh[1]->b_data == qbh->bh[0]->b_data + 1 * 512) &&
0186         likely(qbh->bh[2]->b_data == qbh->bh[0]->b_data + 2 * 512) &&
0187         likely(qbh->bh[3]->b_data == qbh->bh[0]->b_data + 3 * 512)) {
0188         return qbh->data = qbh->bh[0]->b_data;
0189     }
0190 
0191     if (!(qbh->data = kmalloc(2048, GFP_NOFS))) {
0192         pr_err("%s(): out of memory\n", __func__);
0193         goto bail4;
0194     }
0195     return qbh->data;
0196 
0197 bail4:
0198     brelse(qbh->bh[3]);
0199 bail3:
0200     brelse(qbh->bh[2]);
0201 bail2:
0202     brelse(qbh->bh[1]);
0203 bail1:
0204     brelse(qbh->bh[0]);
0205 bail0:
0206     return NULL;
0207 }
0208     
0209 
0210 void hpfs_brelse4(struct quad_buffer_head *qbh)
0211 {
0212     if (unlikely(qbh->data != qbh->bh[0]->b_data))
0213         kfree(qbh->data);
0214     brelse(qbh->bh[0]);
0215     brelse(qbh->bh[1]);
0216     brelse(qbh->bh[2]);
0217     brelse(qbh->bh[3]);
0218 }   
0219 
0220 void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh)
0221 {
0222     if (unlikely(qbh->data != qbh->bh[0]->b_data)) {
0223         memcpy(qbh->bh[0]->b_data, qbh->data + 0 * 512, 512);
0224         memcpy(qbh->bh[1]->b_data, qbh->data + 1 * 512, 512);
0225         memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512);
0226         memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512);
0227     }
0228     mark_buffer_dirty(qbh->bh[0]);
0229     mark_buffer_dirty(qbh->bh[1]);
0230     mark_buffer_dirty(qbh->bh[2]);
0231     mark_buffer_dirty(qbh->bh[3]);
0232 }