~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to fs/nilfs2/direct.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include "alloc.h"
28
28
#include "dat.h"
29
29
 
30
 
static inline __le64 *nilfs_direct_dptrs(const struct nilfs_direct *direct)
 
30
static inline __le64 *nilfs_direct_dptrs(const struct nilfs_bmap *direct)
31
31
{
32
32
        return (__le64 *)
33
 
                ((struct nilfs_direct_node *)direct->d_bmap.b_u.u_data + 1);
 
33
                ((struct nilfs_direct_node *)direct->b_u.u_data + 1);
34
34
}
35
35
 
36
36
static inline __u64
37
 
nilfs_direct_get_ptr(const struct nilfs_direct *direct, __u64 key)
 
37
nilfs_direct_get_ptr(const struct nilfs_bmap *direct, __u64 key)
38
38
{
39
 
        return nilfs_bmap_dptr_to_ptr(*(nilfs_direct_dptrs(direct) + key));
 
39
        return le64_to_cpu(*(nilfs_direct_dptrs(direct) + key));
40
40
}
41
41
 
42
 
static inline void nilfs_direct_set_ptr(struct nilfs_direct *direct,
 
42
static inline void nilfs_direct_set_ptr(struct nilfs_bmap *direct,
43
43
                                        __u64 key, __u64 ptr)
44
44
{
45
 
        *(nilfs_direct_dptrs(direct) + key) = nilfs_bmap_ptr_to_dptr(ptr);
 
45
        *(nilfs_direct_dptrs(direct) + key) = cpu_to_le64(ptr);
46
46
}
47
47
 
48
 
static int nilfs_direct_lookup(const struct nilfs_bmap *bmap,
 
48
static int nilfs_direct_lookup(const struct nilfs_bmap *direct,
49
49
                               __u64 key, int level, __u64 *ptrp)
50
50
{
51
 
        struct nilfs_direct *direct;
52
51
        __u64 ptr;
53
52
 
54
 
        direct = (struct nilfs_direct *)bmap;
55
 
        if ((key > NILFS_DIRECT_KEY_MAX) ||
56
 
            (level != 1) ||     /* XXX: use macro for level 1 */
57
 
            ((ptr = nilfs_direct_get_ptr(direct, key)) ==
58
 
             NILFS_BMAP_INVALID_PTR))
 
53
        if (key > NILFS_DIRECT_KEY_MAX || level != 1)
 
54
                return -ENOENT;
 
55
        ptr = nilfs_direct_get_ptr(direct, key);
 
56
        if (ptr == NILFS_BMAP_INVALID_PTR)
59
57
                return -ENOENT;
60
58
 
61
 
        if (ptrp != NULL)
62
 
                *ptrp = ptr;
 
59
        *ptrp = ptr;
63
60
        return 0;
64
61
}
65
62
 
66
 
static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap,
 
63
static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
67
64
                                      __u64 key, __u64 *ptrp,
68
65
                                      unsigned maxblocks)
69
66
{
70
 
        struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
71
67
        struct inode *dat = NULL;
72
68
        __u64 ptr, ptr2;
73
69
        sector_t blocknr;
74
70
        int ret, cnt;
75
71
 
76
 
        if (key > NILFS_DIRECT_KEY_MAX ||
77
 
            (ptr = nilfs_direct_get_ptr(direct, key)) ==
78
 
            NILFS_BMAP_INVALID_PTR)
 
72
        if (key > NILFS_DIRECT_KEY_MAX)
 
73
                return -ENOENT;
 
74
        ptr = nilfs_direct_get_ptr(direct, key);
 
75
        if (ptr == NILFS_BMAP_INVALID_PTR)
79
76
                return -ENOENT;
80
77
 
81
 
        if (NILFS_BMAP_USE_VBN(bmap)) {
82
 
                dat = nilfs_bmap_get_dat(bmap);
 
78
        if (NILFS_BMAP_USE_VBN(direct)) {
 
79
                dat = nilfs_bmap_get_dat(direct);
83
80
                ret = nilfs_dat_translate(dat, ptr, &blocknr);
84
81
                if (ret < 0)
85
82
                        return ret;
105
102
}
106
103
 
107
104
static __u64
108
 
nilfs_direct_find_target_v(const struct nilfs_direct *direct, __u64 key)
 
105
nilfs_direct_find_target_v(const struct nilfs_bmap *direct, __u64 key)
109
106
{
110
107
        __u64 ptr;
111
108
 
112
 
        ptr = nilfs_bmap_find_target_seq(&direct->d_bmap, key);
 
109
        ptr = nilfs_bmap_find_target_seq(direct, key);
113
110
        if (ptr != NILFS_BMAP_INVALID_PTR)
114
111
                /* sequential access */
115
112
                return ptr;
116
113
        else
117
114
                /* block group */
118
 
                return nilfs_bmap_find_target_in_group(&direct->d_bmap);
119
 
}
120
 
 
121
 
static void nilfs_direct_set_target_v(struct nilfs_direct *direct,
122
 
                                      __u64 key, __u64 ptr)
123
 
{
124
 
        direct->d_bmap.b_last_allocated_key = key;
125
 
        direct->d_bmap.b_last_allocated_ptr = ptr;
 
115
                return nilfs_bmap_find_target_in_group(direct);
126
116
}
127
117
 
128
118
static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
129
119
{
130
 
        struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
131
120
        union nilfs_bmap_ptr_req req;
132
121
        struct inode *dat = NULL;
133
122
        struct buffer_head *bh;
135
124
 
136
125
        if (key > NILFS_DIRECT_KEY_MAX)
137
126
                return -ENOENT;
138
 
        if (nilfs_direct_get_ptr(direct, key) != NILFS_BMAP_INVALID_PTR)
 
127
        if (nilfs_direct_get_ptr(bmap, key) != NILFS_BMAP_INVALID_PTR)
139
128
                return -EEXIST;
140
129
 
141
130
        if (NILFS_BMAP_USE_VBN(bmap)) {
142
 
                req.bpr_ptr = nilfs_direct_find_target_v(direct, key);
 
131
                req.bpr_ptr = nilfs_direct_find_target_v(bmap, key);
143
132
                dat = nilfs_bmap_get_dat(bmap);
144
133
        }
145
134
        ret = nilfs_bmap_prepare_alloc_ptr(bmap, &req, dat);
149
138
                set_buffer_nilfs_volatile(bh);
150
139
 
151
140
                nilfs_bmap_commit_alloc_ptr(bmap, &req, dat);
152
 
                nilfs_direct_set_ptr(direct, key, req.bpr_ptr);
 
141
                nilfs_direct_set_ptr(bmap, key, req.bpr_ptr);
153
142
 
154
143
                if (!nilfs_bmap_dirty(bmap))
155
144
                        nilfs_bmap_set_dirty(bmap);
156
145
 
157
146
                if (NILFS_BMAP_USE_VBN(bmap))
158
 
                        nilfs_direct_set_target_v(direct, key, req.bpr_ptr);
 
147
                        nilfs_bmap_set_target_v(bmap, key, req.bpr_ptr);
159
148
 
160
149
                nilfs_bmap_add_blocks(bmap, 1);
161
150
        }
164
153
 
165
154
static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key)
166
155
{
167
 
        struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
168
156
        union nilfs_bmap_ptr_req req;
169
157
        struct inode *dat;
170
158
        int ret;
171
159
 
172
160
        if (key > NILFS_DIRECT_KEY_MAX ||
173
 
            nilfs_direct_get_ptr(direct, key) == NILFS_BMAP_INVALID_PTR)
 
161
            nilfs_direct_get_ptr(bmap, key) == NILFS_BMAP_INVALID_PTR)
174
162
                return -ENOENT;
175
163
 
176
164
        dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL;
177
 
        req.bpr_ptr = nilfs_direct_get_ptr(direct, key);
 
165
        req.bpr_ptr = nilfs_direct_get_ptr(bmap, key);
178
166
 
179
167
        ret = nilfs_bmap_prepare_end_ptr(bmap, &req, dat);
180
168
        if (!ret) {
181
169
                nilfs_bmap_commit_end_ptr(bmap, &req, dat);
182
 
                nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
 
170
                nilfs_direct_set_ptr(bmap, key, NILFS_BMAP_INVALID_PTR);
183
171
                nilfs_bmap_sub_blocks(bmap, 1);
184
172
        }
185
173
        return ret;
186
174
}
187
175
 
188
 
static int nilfs_direct_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
 
176
static int nilfs_direct_last_key(const struct nilfs_bmap *direct, __u64 *keyp)
189
177
{
190
 
        struct nilfs_direct *direct;
191
178
        __u64 key, lastkey;
192
179
 
193
 
        direct = (struct nilfs_direct *)bmap;
194
180
        lastkey = NILFS_DIRECT_KEY_MAX + 1;
195
181
        for (key = NILFS_DIRECT_KEY_MIN; key <= NILFS_DIRECT_KEY_MAX; key++)
196
182
                if (nilfs_direct_get_ptr(direct, key) !=
210
196
        return key > NILFS_DIRECT_KEY_MAX;
211
197
}
212
198
 
213
 
static int nilfs_direct_gather_data(struct nilfs_bmap *bmap,
 
199
static int nilfs_direct_gather_data(struct nilfs_bmap *direct,
214
200
                                    __u64 *keys, __u64 *ptrs, int nitems)
215
201
{
216
 
        struct nilfs_direct *direct;
217
202
        __u64 key;
218
203
        __u64 ptr;
219
204
        int n;
220
205
 
221
 
        direct = (struct nilfs_direct *)bmap;
222
206
        if (nitems > NILFS_DIRECT_NBLOCKS)
223
207
                nitems = NILFS_DIRECT_NBLOCKS;
224
208
        n = 0;
236
220
int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
237
221
                                    __u64 key, __u64 *keys, __u64 *ptrs, int n)
238
222
{
239
 
        struct nilfs_direct *direct;
240
223
        __le64 *dptrs;
241
224
        int ret, i, j;
242
225
 
252
235
                bmap->b_ops->bop_clear(bmap);
253
236
 
254
237
        /* convert */
255
 
        direct = (struct nilfs_direct *)bmap;
256
 
        dptrs = nilfs_direct_dptrs(direct);
 
238
        dptrs = nilfs_direct_dptrs(bmap);
257
239
        for (i = 0, j = 0; i < NILFS_DIRECT_NBLOCKS; i++) {
258
240
                if ((j < n) && (i == keys[j])) {
259
241
                        dptrs[i] = (i != key) ?
260
 
                                nilfs_bmap_ptr_to_dptr(ptrs[j]) :
 
242
                                cpu_to_le64(ptrs[j]) :
261
243
                                NILFS_BMAP_INVALID_PTR;
262
244
                        j++;
263
245
                } else
268
250
        return 0;
269
251
}
270
252
 
271
 
static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
 
253
static int nilfs_direct_propagate(struct nilfs_bmap *bmap,
272
254
                                  struct buffer_head *bh)
273
255
{
274
 
        struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
275
256
        struct nilfs_palloc_req oldreq, newreq;
276
257
        struct inode *dat;
277
258
        __u64 key;
283
264
 
284
265
        dat = nilfs_bmap_get_dat(bmap);
285
266
        key = nilfs_bmap_data_get_key(bmap, bh);
286
 
        ptr = nilfs_direct_get_ptr(direct, key);
 
267
        ptr = nilfs_direct_get_ptr(bmap, key);
287
268
        if (!buffer_nilfs_volatile(bh)) {
288
269
                oldreq.pr_entry_nr = ptr;
289
270
                newreq.pr_entry_nr = ptr;
293
274
                nilfs_dat_commit_update(dat, &oldreq, &newreq,
294
275
                                        bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
295
276
                set_buffer_nilfs_volatile(bh);
296
 
                nilfs_direct_set_ptr(direct, key, newreq.pr_entry_nr);
 
277
                nilfs_direct_set_ptr(bmap, key, newreq.pr_entry_nr);
297
278
        } else
298
279
                ret = nilfs_dat_mark_dirty(dat, ptr);
299
280
 
300
281
        return ret;
301
282
}
302
283
 
303
 
static int nilfs_direct_assign_v(struct nilfs_direct *direct,
 
284
static int nilfs_direct_assign_v(struct nilfs_bmap *direct,
304
285
                                 __u64 key, __u64 ptr,
305
286
                                 struct buffer_head **bh,
306
287
                                 sector_t blocknr,
307
288
                                 union nilfs_binfo *binfo)
308
289
{
309
 
        struct inode *dat = nilfs_bmap_get_dat(&direct->d_bmap);
 
290
        struct inode *dat = nilfs_bmap_get_dat(direct);
310
291
        union nilfs_bmap_ptr_req req;
311
292
        int ret;
312
293
 
314
295
        ret = nilfs_dat_prepare_start(dat, &req.bpr_req);
315
296
        if (!ret) {
316
297
                nilfs_dat_commit_start(dat, &req.bpr_req, blocknr);
317
 
                binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
318
 
                binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
 
298
                binfo->bi_v.bi_vblocknr = cpu_to_le64(ptr);
 
299
                binfo->bi_v.bi_blkoff = cpu_to_le64(key);
319
300
        }
320
301
        return ret;
321
302
}
322
303
 
323
 
static int nilfs_direct_assign_p(struct nilfs_direct *direct,
 
304
static int nilfs_direct_assign_p(struct nilfs_bmap *direct,
324
305
                                 __u64 key, __u64 ptr,
325
306
                                 struct buffer_head **bh,
326
307
                                 sector_t blocknr,
328
309
{
329
310
        nilfs_direct_set_ptr(direct, key, blocknr);
330
311
 
331
 
        binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key);
 
312
        binfo->bi_dat.bi_blkoff = cpu_to_le64(key);
332
313
        binfo->bi_dat.bi_level = 0;
333
314
 
334
315
        return 0;
339
320
                               sector_t blocknr,
340
321
                               union nilfs_binfo *binfo)
341
322
{
342
 
        struct nilfs_direct *direct;
343
323
        __u64 key;
344
324
        __u64 ptr;
345
325
 
346
 
        direct = (struct nilfs_direct *)bmap;
347
326
        key = nilfs_bmap_data_get_key(bmap, *bh);
348
327
        if (unlikely(key > NILFS_DIRECT_KEY_MAX)) {
349
328
                printk(KERN_CRIT "%s: invalid key: %llu\n", __func__,
350
329
                       (unsigned long long)key);
351
330
                return -EINVAL;
352
331
        }
353
 
        ptr = nilfs_direct_get_ptr(direct, key);
 
332
        ptr = nilfs_direct_get_ptr(bmap, key);
354
333
        if (unlikely(ptr == NILFS_BMAP_INVALID_PTR)) {
355
334
                printk(KERN_CRIT "%s: invalid pointer: %llu\n", __func__,
356
335
                       (unsigned long long)ptr);
358
337
        }
359
338
 
360
339
        return NILFS_BMAP_USE_VBN(bmap) ?
361
 
                nilfs_direct_assign_v(direct, key, ptr, bh, blocknr, binfo) :
362
 
                nilfs_direct_assign_p(direct, key, ptr, bh, blocknr, binfo);
 
340
                nilfs_direct_assign_v(bmap, key, ptr, bh, blocknr, binfo) :
 
341
                nilfs_direct_assign_p(bmap, key, ptr, bh, blocknr, binfo);
363
342
}
364
343
 
365
344
static const struct nilfs_bmap_operations nilfs_direct_ops = {