~ubuntu-branches/debian/stretch/jfsutils/stretch

« back to all changes in this revision

Viewing changes to fsck/dirindex.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Hornburg (Racke)
  • Date: 2006-08-02 21:15:09 UTC
  • mfrom: (1.2.2 upstream) (2.1.3 breezy)
  • Revision ID: james.westby@ubuntu.com-20060802211509-eoqwjtlgla5tu9dt
* new upstream release fixing stack buffer overflow (Closes: #343638)
* keep only reference to GPL in debian/copyright
* mark udeb package as such properly and create dependencies 
  (Closes: #381245, thanks to Frans Pop <fjp@debian.org> for the patch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *   Copyright (C) International Business Machines Corp., 2004
 
2
 *   Copyright (C) International Business Machines Corp., 2004,2005
3
3
 *
4
4
 *   This program is free software;  you can redistribute it and/or modify
5
5
 *   it under the terms of the GNU General Public License as published by
6
 
 *   the Free Software Foundation; either version 2 of the License, or 
 
6
 *   the Free Software Foundation; either version 2 of the License, or
7
7
 *   (at your option) any later version.
8
 
 * 
 
8
 *
9
9
 *   This program is distributed in the hope that it will be useful,
10
10
 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
11
11
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12
12
 *   the GNU General Public License for more details.
13
13
 *
14
14
 *   You should have received a copy of the GNU General Public License
15
 
 *   along with this program;  if not, write to the Free Software 
 
15
 *   along with this program;  if not, write to the Free Software
16
16
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 */
 
18
#include <config.h>
 
19
#include <stdlib.h>
 
20
#include <errno.h>
18
21
/* defines and includes common among the fsck.jfs modules */
19
22
#include "xfsckint.h"
20
 
#include <errno.h>
 
23
#include "devices.h"
 
24
#include "message.h"
21
25
 
22
26
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
23
27
 *
35
39
 */
36
40
extern struct fsck_agg_record *agg_recptr;
37
41
 
38
 
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
39
 
 *
40
 
 * For message processing
41
 
 *
42
 
 *      defined in xchkdsk.c
43
 
 */
44
 
 
45
 
extern char *verbose_msg_ptr;
46
 
 
47
 
extern char *Vol_Label;
48
 
 
49
 
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
50
 
 *
51
 
 * Device information.
52
 
 *
53
 
 *      defined in xchkdsk.c
54
 
 */
55
 
extern HFILE Dev_IOPort;
56
 
extern uint32_t Dev_blksize;
57
 
 
58
42
/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
59
43
 *
60
44
 * The following are internal to this file
71
55
        long long address;
72
56
        struct dir_index_page *next;
73
57
        struct dir_index_page *prev;
 
58
        int flag;
74
59
        struct dir_table_slot table[512];
75
60
};
76
61
 
 
62
#define DIPAGE_DIRTY 1
 
63
 
77
64
struct dir_index_page *dir_index_buffers;
78
65
 
79
66
struct dir_index_page *free_di_page;    /* free list */
99
86
                page->address = 0;
100
87
                page->next = last;
101
88
                page->prev = NULL;      /* Not used on free list */
 
89
                page->flag = 0;
102
90
                last = page;
103
91
                page++;
104
92
        }
108
96
        return FSCK_OK;
109
97
}
110
98
 
111
 
 
112
 
static struct dir_table_slot *read_index_page(long long address)
113
 
{
 
99
static int write_index_page(struct dir_index_page *page)
 
100
{
 
101
        int rc;
 
102
 
 
103
        rc = ujfs_rw_diskblocks(Dev_IOPort, page->address << sb_ptr->s_l2bsize,
 
104
                                PSIZE, page->table, PUT);
 
105
 
 
106
        return rc;
 
107
}
 
108
 
 
109
static struct dir_table_slot *read_index_page(struct dinode *inoptr,
 
110
                                              uint cookie)
 
111
{
 
112
        long long address;
 
113
        int64_t blkno;
 
114
        int8_t match_found;
 
115
        int64_t offset;
114
116
        struct dir_index_page *page;
115
117
        int rc;
 
118
        xad_t *xad_ptr;
 
119
 
 
120
        offset = (cookie - 2) * sizeof (struct dir_table_slot);
 
121
        blkno = (offset >> L2PSIZE) << (L2PSIZE - sb_ptr->s_l2bsize);
 
122
 
 
123
        rc = xTree_search(inoptr, blkno, &xad_ptr, &match_found);
 
124
 
 
125
        if (rc || !match_found)
 
126
                return NULL;
 
127
 
 
128
        address = addressXAD(xad_ptr);
116
129
 
117
130
        /* Search cache.  Is it worthwhile to build a hash? */
118
131
        for (page = mru_di_page; page; page = page->next) {
139
152
                free_di_page = page->next;
140
153
        } else {
141
154
                page = lru_di_page;
 
155
                if (page->flag & DIPAGE_DIRTY)
 
156
                        write_index_page(page);
142
157
                lru_di_page = page->prev;
143
158
                lru_di_page->next = NULL;
144
159
        }
145
160
        page->address = address;
 
161
        page->flag = 0;
146
162
        rc = ujfs_rw_diskblocks(Dev_IOPort, address << sb_ptr->s_l2bsize,
147
163
                                PSIZE, page->table, GET);
148
164
        if (rc) {
163
179
        return page->table;
164
180
}
165
181
 
166
 
#ifdef NOT_YET
167
 
static int write_index_page(struct dir_table_slot *table)
168
 
{
169
 
        int rc;
170
 
 
 
182
int flush_index_pages()
 
183
{
 
184
        struct dir_index_page *page;
 
185
        int rc = 0, rc2;
 
186
 
 
187
        for (page = mru_di_page; page; page = page->next) {
 
188
                if (page->flag & DIPAGE_DIRTY) {
 
189
                        rc2 = write_index_page(page);
 
190
                        if (!rc)
 
191
                                rc = rc2;
 
192
                        page->flag &= ~DIPAGE_DIRTY;
 
193
                }
 
194
        }
 
195
        return rc;
 
196
}
 
197
 
 
198
static void dirty_index_page(struct dir_table_slot *table)
 
199
{
171
200
        /* Should only be called on most recent page */
172
201
        if (table != mru_di_page->table) {
173
 
                /* TODO: replace with more appropriate message & rc */
 
202
                /* Really shoudn't happen. */
174
203
                printf("You messed up, Shaggy.  write_index_page mismatch.\n");
175
 
                return EIO;
 
204
                return;
176
205
        }
177
 
 
178
 
        rc = ujfs_rw_diskblocks(Dev_IOPort,
179
 
                                mru_di_page->address << sb_ptr->s_l2bsize,
180
 
                                PSIZE, table, PUT);
181
 
 
182
 
        return rc;
 
206
        mru_di_page->flag |= DIPAGE_DIRTY;
183
207
}
184
 
#endif
185
208
 
186
209
void verify_dir_index(struct fsck_inode_record *inorecptr,
187
210
                      struct dinode *inoptr,
189
212
                      int dtindex,
190
213
                      uint cookie)
191
214
{
192
 
        int64_t blkno;
193
 
        int8_t match_found;
194
 
        int64_t offset;
195
215
        int64_t page_addr;
196
 
        int rc;
197
216
        struct dir_table_slot *slot;
198
217
        struct dir_table_slot *table;
199
 
        xad_t *xad_ptr;
200
218
 
201
219
        if (!inorecptr->check_dir_index)
202
220
                return;
213
231
        if ((cookie < 2) || (cookie >= inoptr->di_next_index)) {
214
232
                fsck_send_msg(fsck_BAD_COOKIE);
215
233
                goto error_found;
216
 
                return;
217
234
        }
218
235
 
219
236
        if (inoptr->di_next_index <= (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
220
237
                table = inoptr->di_dirtable;
221
238
                slot = &table[cookie - 2];
222
239
        } else {
223
 
                offset = (cookie - 2) * sizeof (struct dir_table_slot);
224
 
                blkno = (offset >> L2PSIZE) << (L2PSIZE - sb_ptr->s_l2bsize);
225
 
                rc = xTree_search(inoptr, blkno, &xad_ptr, &match_found);
226
 
                if (rc || !match_found) {
227
 
                        fsck_send_msg(fsck_PAGE_NOT_FOUND);
228
 
                        goto error_found;
229
 
                }
230
 
                table = read_index_page(addressXAD(xad_ptr));
 
240
                table = read_index_page(inoptr, cookie);
231
241
                if (!table) {
232
242
                        fsck_send_msg(fsck_READ_FAILED);
233
243
                        goto error_found;
253
263
        agg_recptr->corrections_needed = 1;
254
264
        return;
255
265
}
 
266
 
 
267
void modify_index(struct dinode *inoptr,
 
268
                  int64_t page_addr,
 
269
                  int dtindex,
 
270
                  uint cookie)
 
271
{
 
272
        struct dir_table_slot *slot;
 
273
        struct dir_table_slot *table;
 
274
 
 
275
        if (cookie < 2 || (cookie >= inoptr->di_next_index))
 
276
                return;
 
277
 
 
278
        if (inoptr->di_next_index <= (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
 
279
                slot = &inoptr->di_dirtable[cookie - 2];
 
280
                DTSaddress(slot, page_addr);
 
281
                slot->slot = dtindex;
 
282
                return;
 
283
        }
 
284
        table = read_index_page(inoptr, cookie);
 
285
        if (!table)
 
286
                return;
 
287
 
 
288
        slot = &table[(cookie - 2) % 512];
 
289
        DTSaddress(slot, page_addr);
 
290
        slot->slot = dtindex;
 
291
 
 
292
        dirty_index_page(table);
 
293
}