linux/fs/ufs/util.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/ufs/util.c
   3 *
   4 * Copyright (C) 1998
   5 * Daniel Pirkl <daniel.pirkl@email.cz>
   6 * Charles University, Faculty of Mathematics and Physics
   7 */
   8 
   9#include <linux/string.h>
  10#include <linux/slab.h>
  11#include <linux/buffer_head.h>
  12
  13#include "ufs_fs.h"
  14#include "ufs.h"
  15#include "swab.h"
  16#include "util.h"
  17
  18struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi,
  19        struct super_block *sb, u64 fragment, u64 size)
  20{
  21        struct ufs_buffer_head * ubh;
  22        unsigned i, j ;
  23        u64  count = 0;
  24        if (size & ~uspi->s_fmask)
  25                return NULL;
  26        count = size >> uspi->s_fshift;
  27        if (count > UFS_MAXFRAG)
  28                return NULL;
  29        ubh = kmalloc (sizeof (struct ufs_buffer_head), GFP_NOFS);
  30        if (!ubh)
  31                return NULL;
  32        ubh->fragment = fragment;
  33        ubh->count = count;
  34        for (i = 0; i < count; i++)
  35                if (!(ubh->bh[i] = sb_bread(sb, fragment + i)))
  36                        goto failed;
  37        for (; i < UFS_MAXFRAG; i++)
  38                ubh->bh[i] = NULL;
  39        return ubh;
  40failed:
  41        for (j = 0; j < i; j++)
  42                brelse (ubh->bh[j]);
  43        kfree(ubh);
  44        return NULL;
  45}
  46
  47struct ufs_buffer_head * ubh_bread_uspi (struct ufs_sb_private_info * uspi,
  48        struct super_block *sb, u64 fragment, u64 size)
  49{
  50        unsigned i, j;
  51        u64 count = 0;
  52        if (size & ~uspi->s_fmask)
  53                return NULL;
  54        count = size >> uspi->s_fshift;
  55        if (count <= 0 || count > UFS_MAXFRAG)
  56                return NULL;
  57        USPI_UBH(uspi)->fragment = fragment;
  58        USPI_UBH(uspi)->count = count;
  59        for (i = 0; i < count; i++)
  60                if (!(USPI_UBH(uspi)->bh[i] = sb_bread(sb, fragment + i)))
  61                        goto failed;
  62        for (; i < UFS_MAXFRAG; i++)
  63                USPI_UBH(uspi)->bh[i] = NULL;
  64        return USPI_UBH(uspi);
  65failed:
  66        for (j = 0; j < i; j++)
  67                brelse (USPI_UBH(uspi)->bh[j]);
  68        return NULL;
  69}
  70
  71void ubh_brelse (struct ufs_buffer_head * ubh)
  72{
  73        unsigned i;
  74        if (!ubh)
  75                return;
  76        for (i = 0; i < ubh->count; i++)
  77                brelse (ubh->bh[i]);
  78        kfree (ubh);
  79}
  80
  81void ubh_brelse_uspi (struct ufs_sb_private_info * uspi)
  82{
  83        unsigned i;
  84        if (!USPI_UBH(uspi))
  85                return;
  86        for ( i = 0; i < USPI_UBH(uspi)->count; i++ ) {
  87                brelse (USPI_UBH(uspi)->bh[i]);
  88                USPI_UBH(uspi)->bh[i] = NULL;
  89        }
  90}
  91
  92void ubh_mark_buffer_dirty (struct ufs_buffer_head * ubh)
  93{
  94        unsigned i;
  95        if (!ubh)
  96                return;
  97        for ( i = 0; i < ubh->count; i++ )
  98                mark_buffer_dirty (ubh->bh[i]);
  99}
 100
 101void ubh_mark_buffer_uptodate (struct ufs_buffer_head * ubh, int flag)
 102{
 103        unsigned i;
 104        if (!ubh)
 105                return;
 106        if (flag) {
 107                for ( i = 0; i < ubh->count; i++ )
 108                        set_buffer_uptodate (ubh->bh[i]);
 109        } else {
 110                for ( i = 0; i < ubh->count; i++ )
 111                        clear_buffer_uptodate (ubh->bh[i]);
 112        }
 113}
 114
 115void ubh_sync_block(struct ufs_buffer_head *ubh)
 116{
 117        if (ubh) {
 118                unsigned i;
 119
 120                for (i = 0; i < ubh->count; i++)
 121                        write_dirty_buffer(ubh->bh[i], WRITE);
 122
 123                for (i = 0; i < ubh->count; i++)
 124                        wait_on_buffer(ubh->bh[i]);
 125        }
 126}
 127
 128void ubh_bforget (struct ufs_buffer_head * ubh)
 129{
 130        unsigned i;
 131        if (!ubh) 
 132                return;
 133        for ( i = 0; i < ubh->count; i++ ) if ( ubh->bh[i] ) 
 134                bforget (ubh->bh[i]);
 135}
 136 
 137int ubh_buffer_dirty (struct ufs_buffer_head * ubh)
 138{
 139        unsigned i;
 140        unsigned result = 0;
 141        if (!ubh)
 142                return 0;
 143        for ( i = 0; i < ubh->count; i++ )
 144                result |= buffer_dirty(ubh->bh[i]);
 145        return result;
 146}
 147
 148void _ubh_ubhcpymem_(struct ufs_sb_private_info * uspi, 
 149        unsigned char * mem, struct ufs_buffer_head * ubh, unsigned size)
 150{
 151        unsigned len, bhno;
 152        if (size > (ubh->count << uspi->s_fshift))
 153                size = ubh->count << uspi->s_fshift;
 154        bhno = 0;
 155        while (size) {
 156                len = min_t(unsigned int, size, uspi->s_fsize);
 157                memcpy (mem, ubh->bh[bhno]->b_data, len);
 158                mem += uspi->s_fsize;
 159                size -= len;
 160                bhno++;
 161        }
 162}
 163
 164void _ubh_memcpyubh_(struct ufs_sb_private_info * uspi, 
 165        struct ufs_buffer_head * ubh, unsigned char * mem, unsigned size)
 166{
 167        unsigned len, bhno;
 168        if (size > (ubh->count << uspi->s_fshift))
 169                size = ubh->count << uspi->s_fshift;
 170        bhno = 0;
 171        while (size) {
 172                len = min_t(unsigned int, size, uspi->s_fsize);
 173                memcpy (ubh->bh[bhno]->b_data, mem, len);
 174                mem += uspi->s_fsize;
 175                size -= len;
 176                bhno++;
 177        }
 178}
 179
 180dev_t
 181ufs_get_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi)
 182{
 183        __u32 fs32;
 184        dev_t dev;
 185
 186        if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86)
 187                fs32 = fs32_to_cpu(sb, ufsi->i_u1.i_data[1]);
 188        else
 189                fs32 = fs32_to_cpu(sb, ufsi->i_u1.i_data[0]);
 190        switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
 191        case UFS_ST_SUNx86:
 192        case UFS_ST_SUN:
 193                if ((fs32 & 0xffff0000) == 0 ||
 194                    (fs32 & 0xffff0000) == 0xffff0000)
 195                        dev = old_decode_dev(fs32 & 0x7fff);
 196                else
 197                        dev = MKDEV(sysv_major(fs32), sysv_minor(fs32));
 198                break;
 199
 200        default:
 201                dev = old_decode_dev(fs32);
 202                break;
 203        }
 204        return dev;
 205}
 206
 207void
 208ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev)
 209{
 210        __u32 fs32;
 211
 212        switch (UFS_SB(sb)->s_flags & UFS_ST_MASK) {
 213        case UFS_ST_SUNx86:
 214        case UFS_ST_SUN:
 215                fs32 = sysv_encode_dev(dev);
 216                if ((fs32 & 0xffff8000) == 0) {
 217                        fs32 = old_encode_dev(dev);
 218                }
 219                break;
 220
 221        default:
 222                fs32 = old_encode_dev(dev);
 223                break;
 224        }
 225        if ((UFS_SB(sb)->s_flags & UFS_ST_MASK) == UFS_ST_SUNx86)
 226                ufsi->i_u1.i_data[1] = cpu_to_fs32(sb, fs32);
 227        else
 228                ufsi->i_u1.i_data[0] = cpu_to_fs32(sb, fs32);
 229}
 230
 231/**
 232 * ufs_get_locked_page() - locate, pin and lock a pagecache page, if not exist
 233 * read it from disk.
 234 * @mapping: the address_space to search
 235 * @index: the page index
 236 *
 237 * Locates the desired pagecache page, if not exist we'll read it,
 238 * locks it, increments its reference
 239 * count and returns its address.
 240 *
 241 */
 242
 243struct page *ufs_get_locked_page(struct address_space *mapping,
 244                                 pgoff_t index)
 245{
 246        struct page *page;
 247
 248        page = find_lock_page(mapping, index);
 249        if (!page) {
 250                page = read_mapping_page(mapping, index, NULL);
 251
 252                if (IS_ERR(page)) {
 253                        printk(KERN_ERR "ufs_change_blocknr: "
 254                               "read_mapping_page error: ino %lu, index: %lu\n",
 255                               mapping->host->i_ino, index);
 256                        goto out;
 257                }
 258
 259                lock_page(page);
 260
 261                if (unlikely(page->mapping == NULL)) {
 262                        /* Truncate got there first */
 263                        unlock_page(page);
 264                        page_cache_release(page);
 265                        page = NULL;
 266                        goto out;
 267                }
 268
 269                if (!PageUptodate(page) || PageError(page)) {
 270                        unlock_page(page);
 271                        page_cache_release(page);
 272
 273                        printk(KERN_ERR "ufs_change_blocknr: "
 274                               "can not read page: ino %lu, index: %lu\n",
 275                               mapping->host->i_ino, index);
 276
 277                        page = ERR_PTR(-EIO);
 278                }
 279        }
 280out:
 281        return page;
 282}
 283
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.