linux-old/fs/udf/ialloc.c
<<
>>
Prefs
   1/*
   2 * ialloc.c
   3 *
   4 * PURPOSE
   5 *      Inode allocation handling routines for the OSTA-UDF(tm) filesystem.
   6 *
   7 * CONTACTS
   8 *      E-mail regarding any portion of the Linux UDF file system should be
   9 *      directed to the development team mailing list (run by majordomo):
  10 *              linux_udf@hpesjro.fc.hp.com
  11 *
  12 * COPYRIGHT
  13 *      This file is distributed under the terms of the GNU General Public
  14 *      License (GPL). Copies of the GPL can be obtained from:
  15 *              ftp://prep.ai.mit.edu/pub/gnu/GPL
  16 *      Each contributing author retains all rights to their own work.
  17 *
  18 *  (C) 1998-2001 Ben Fennema
  19 *
  20 * HISTORY
  21 *
  22 *  02/24/99 blf  Created.
  23 *
  24 */
  25
  26#include "udfdecl.h"
  27#include <linux/fs.h>
  28#include <linux/locks.h>
  29#include <linux/quotaops.h>
  30#include <linux/udf_fs.h>
  31
  32#include "udf_i.h"
  33#include "udf_sb.h"
  34
  35void udf_free_inode(struct inode * inode)
  36{
  37        struct super_block * sb = inode->i_sb;
  38        int is_directory;
  39        unsigned long ino;
  40
  41        ino = inode->i_ino;
  42
  43        /*
  44         * Note: we must free any quota before locking the superblock,
  45         * as writing the quota to disk may need the lock as well.
  46         */
  47        DQUOT_FREE_INODE(inode);
  48        DQUOT_DROP(inode);
  49
  50        lock_super(sb);
  51
  52        is_directory = S_ISDIR(inode->i_mode);
  53
  54        clear_inode(inode);
  55
  56        if (UDF_SB_LVIDBH(sb))
  57        {
  58                if (is_directory)
  59                        UDF_SB_LVIDIU(sb)->numDirs =
  60                                cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) - 1);
  61                else
  62                        UDF_SB_LVIDIU(sb)->numFiles =
  63                                cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) - 1);
  64                
  65                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
  66        }
  67        unlock_super(sb);
  68
  69        udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1);
  70}
  71
  72struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
  73{
  74        struct super_block *sb;
  75        struct inode * inode;
  76        int block;
  77        uint32_t start = UDF_I_LOCATION(dir).logicalBlockNum;
  78
  79        sb = dir->i_sb;
  80        inode = new_inode(sb);
  81
  82        if (!inode)
  83        {
  84                *err = -ENOMEM;
  85                return NULL;
  86        }
  87        *err = -ENOSPC;
  88
  89        block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum,
  90                start, err);
  91        if (*err)
  92        {
  93                iput(inode);
  94                return NULL;
  95        }
  96        lock_super(sb);
  97
  98        if (UDF_SB_LVIDBH(sb))
  99        {
 100                struct logicalVolHeaderDesc *lvhd;
 101                uint64_t uniqueID;
 102                lvhd = (struct logicalVolHeaderDesc *)(UDF_SB_LVID(sb)->logicalVolContentsUse);
 103                if (S_ISDIR(mode))
 104                        UDF_SB_LVIDIU(sb)->numDirs =
 105                                cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numDirs) + 1);
 106                else
 107                        UDF_SB_LVIDIU(sb)->numFiles =
 108                                cpu_to_le32(le32_to_cpu(UDF_SB_LVIDIU(sb)->numFiles) + 1);
 109                UDF_I_UNIQUE(inode) = uniqueID = le64_to_cpu(lvhd->uniqueID);
 110                if (!(++uniqueID & 0x00000000FFFFFFFFUL))
 111                        uniqueID += 16;
 112                lvhd->uniqueID = cpu_to_le64(uniqueID);
 113                mark_buffer_dirty(UDF_SB_LVIDBH(sb));
 114        }
 115        inode->i_mode = mode;
 116        inode->i_uid = current->fsuid;
 117        if (dir->i_mode & S_ISGID)
 118        {
 119                inode->i_gid = dir->i_gid;
 120                if (S_ISDIR(mode))
 121                        mode |= S_ISGID;
 122        }
 123        else
 124                inode->i_gid = current->fsgid;
 125
 126        UDF_I_LOCATION(inode).logicalBlockNum = block;
 127        UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum;
 128        inode->i_ino = udf_get_lb_pblock(sb, UDF_I_LOCATION(inode), 0);
 129        inode->i_blksize = PAGE_SIZE;
 130        inode->i_blocks = 0;
 131        UDF_I_LENEATTR(inode) = 0;
 132        UDF_I_LENALLOC(inode) = 0;
 133        if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE))
 134        {
 135                UDF_I_EXTENDED_FE(inode) = 1;
 136                UDF_UPDATE_UDFREV(inode->i_sb, UDF_VERS_USE_EXTENDED_FE);
 137        }
 138        else
 139                UDF_I_EXTENDED_FE(inode) = 0;
 140        if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
 141                UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_IN_ICB;
 142        else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
 143                UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_SHORT;
 144        else
 145                UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
 146        inode->i_mtime = inode->i_atime = inode->i_ctime =
 147                UDF_I_CRTIME(inode) = CURRENT_TIME;
 148        UDF_I_UMTIME(inode) = UDF_I_UCTIME(inode) =
 149                UDF_I_UCRTIME(inode) = CURRENT_UTIME;
 150        UDF_I_NEW_INODE(inode) = 1;
 151        insert_inode_hash(inode);
 152        mark_inode_dirty(inode);
 153
 154        unlock_super(sb);
 155        if (DQUOT_ALLOC_INODE(inode))
 156        {
 157                DQUOT_DROP(inode);
 158                inode->i_flags |= S_NOQUOTA;
 159                inode->i_nlink = 0;
 160                iput(inode);
 161                *err = -EDQUOT;
 162                return NULL;
 163        }
 164
 165        *err = 0;
 166        return inode;
 167}
 168
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.