OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [LINUX_2_4_26_OR32/] [linux/] [linux-2.4/] [fs/] [udf/] [truncate.c] - Blame information for rev 1279

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * truncate.c
3
 *
4
 * PURPOSE
5
 *      Truncate 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) 1999-2001 Ben Fennema
19
 *  (C) 1999 Stelias Computing Inc
20
 *
21
 * HISTORY
22
 *
23
 *  02/24/99 blf  Created.
24
 *
25
 */
26
 
27
#include "udfdecl.h"
28
#include <linux/fs.h>
29
#include <linux/mm.h>
30
#include <linux/udf_fs.h>
31
 
32
#include "udf_i.h"
33
#include "udf_sb.h"
34
 
35
static void extent_trunc(struct inode * inode, lb_addr bloc, int extoffset,
36
        lb_addr eloc, int8_t etype, uint32_t elen, struct buffer_head *bh, uint32_t nelen)
37
{
38
        lb_addr neloc = { 0, 0 };
39
        int last_block = (elen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
40
        int first_block = (nelen + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
41
 
42
        if (nelen)
43
        {
44
                if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
45
                {
46
                        udf_free_blocks(inode->i_sb, inode, eloc, 0, last_block);
47
                        etype = (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30);
48
                }
49
                else
50
                        neloc = eloc;
51
                nelen = (etype << 30) | nelen;
52
        }
53
 
54
        if (elen != nelen)
55
        {
56
                udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
57
                if (last_block - first_block > 0)
58
                {
59
                        if (etype == (EXT_RECORDED_ALLOCATED >> 30))
60
                                mark_inode_dirty(inode);
61
 
62
                        if (etype != (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
63
                                udf_free_blocks(inode->i_sb, inode, eloc, first_block, last_block - first_block);
64
                }
65
        }
66
}
67
 
68
void udf_truncate_extents(struct inode * inode)
69
{
70
        lb_addr bloc, eloc, neloc = { 0, 0 };
71
        uint32_t extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
72
        int8_t etype;
73
        int first_block = inode->i_size >> inode->i_sb->s_blocksize_bits;
74
        struct buffer_head *bh = NULL;
75
        int adsize;
76
 
77
        if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
78
                adsize = sizeof(short_ad);
79
        else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
80
                adsize = sizeof(long_ad);
81
        else
82
                adsize = 0;
83
 
84
        etype = inode_bmap(inode, first_block, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
85
        offset += (inode->i_size & (inode->i_sb->s_blocksize - 1));
86
        if (etype != -1)
87
        {
88
                extoffset -= adsize;
89
                extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, offset);
90
                extoffset += adsize;
91
 
92
                if (offset)
93
                        lenalloc = extoffset;
94
                else
95
                        lenalloc = extoffset - adsize;
96
 
97
                if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
98
                        lenalloc -= udf_file_entry_alloc_offset(inode);
99
                else
100
                        lenalloc -= sizeof(struct allocExtDesc);
101
 
102
                while ((etype = udf_current_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0)) != -1)
103
                {
104
                        if (etype == (EXT_NEXT_EXTENT_ALLOCDECS >> 30))
105
                        {
106
                                udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 0);
107
                                extoffset = 0;
108
                                if (lelen)
109
                                {
110
                                        if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
111
                                                memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
112
                                        else
113
                                                memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
114
                                        udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
115
                                }
116
                                else
117
                                {
118
                                        if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
119
                                        {
120
                                                UDF_I_LENALLOC(inode) = lenalloc;
121
                                                mark_inode_dirty(inode);
122
                                        }
123
                                        else
124
                                        {
125
                                                struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
126
                                                aed->lengthAllocDescs = cpu_to_le32(lenalloc);
127
                                                if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
128
                                                        udf_update_tag(bh->b_data, lenalloc +
129
                                                                sizeof(struct allocExtDesc));
130
                                                else
131
                                                        udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
132
                                                mark_buffer_dirty_inode(bh, inode);
133
                                        }
134
                                }
135
 
136
                                udf_release_data(bh);
137
                                bh = NULL;
138
 
139
                                bloc = eloc;
140
                                if (elen)
141
                                        lelen = (elen + inode->i_sb->s_blocksize - 1) >>
142
                                                inode->i_sb->s_blocksize_bits;
143
                                else
144
                                        lelen = 1;
145
                        }
146
                        else
147
                        {
148
                                extent_trunc(inode, bloc, extoffset, eloc, etype, elen, bh, 0);
149
                                extoffset += adsize;
150
                        }
151
                }
152
 
153
                if (lelen)
154
                {
155
                        if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
156
                                memset(bh->b_data, 0x00, udf_file_entry_alloc_offset(inode));
157
                        else
158
                                memset(bh->b_data, 0x00, sizeof(struct allocExtDesc));
159
                        udf_free_blocks(inode->i_sb, inode, bloc, 0, lelen);
160
                }
161
                else
162
                {
163
                        if (!memcmp(&UDF_I_LOCATION(inode), &bloc, sizeof(lb_addr)))
164
                        {
165
                                UDF_I_LENALLOC(inode) = lenalloc;
166
                                mark_inode_dirty(inode);
167
                        }
168
                        else
169
                        {
170
                                struct allocExtDesc *aed = (struct allocExtDesc *)(bh->b_data);
171
                                aed->lengthAllocDescs = cpu_to_le32(lenalloc);
172
                                if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201)
173
                                        udf_update_tag(bh->b_data, lenalloc +
174
                                                sizeof(struct allocExtDesc));
175
                                else
176
                                        udf_update_tag(bh->b_data, sizeof(struct allocExtDesc));
177
                                mark_buffer_dirty_inode(bh, inode);
178
                        }
179
                }
180
        }
181
        else if (inode->i_size)
182
        {
183
                if (offset)
184
                {
185
                        extoffset -= adsize;
186
                        etype = udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 1);
187
                        if (etype == (EXT_NOT_RECORDED_NOT_ALLOCATED >> 30))
188
                        {
189
                                extoffset -= adsize;
190
                                elen = EXT_NOT_RECORDED_NOT_ALLOCATED | (elen + offset);
191
                                udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 0);
192
                        }
193
                        else if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30))
194
                        {
195
                                lb_addr neloc = { 0, 0 };
196
                                extoffset -= adsize;
197
                                nelen = EXT_NOT_RECORDED_NOT_ALLOCATED |
198
                                        ((elen + offset + inode->i_sb->s_blocksize - 1) &
199
                                        ~(inode->i_sb->s_blocksize - 1));
200
                                udf_write_aext(inode, bloc, &extoffset, neloc, nelen, bh, 1);
201
                                udf_add_aext(inode, &bloc, &extoffset, eloc, (etype << 30) | elen, &bh, 1);
202
                        }
203
                        else
204
                        {
205
                                if (elen & (inode->i_sb->s_blocksize - 1))
206
                                {
207
                                        extoffset -= adsize;
208
                                        elen = EXT_RECORDED_ALLOCATED |
209
                                                ((elen + inode->i_sb->s_blocksize - 1) &
210
                                                ~(inode->i_sb->s_blocksize - 1));
211
                                        udf_write_aext(inode, bloc, &extoffset, eloc, elen, bh, 1);
212
                                }
213
                                memset(&eloc, 0x00, sizeof(lb_addr));
214
                                elen = EXT_NOT_RECORDED_NOT_ALLOCATED | offset;
215
                                udf_add_aext(inode, &bloc, &extoffset, eloc, elen, &bh, 1);
216
                        }
217
                }
218
        }
219
        UDF_I_LENEXTENTS(inode) = inode->i_size;
220
 
221
        udf_release_data(bh);
222
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.