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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [ext4/] [xattr.c] - Blame information for rev 79

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

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * linux/fs/ext4/xattr.c
3
 *
4
 * Copyright (C) 2001-2003 Andreas Gruenbacher, <agruen@suse.de>
5
 *
6
 * Fix by Harrison Xing <harrison@mountainviewdata.com>.
7
 * Ext4 code with a lot of help from Eric Jarman <ejarman@acm.org>.
8
 * Extended attributes for symlinks and special files added per
9
 *  suggestion of Luka Renko <luka.renko@hermes.si>.
10
 * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
11
 *  Red Hat Inc.
12
 * ea-in-inode support by Alex Tomas <alex@clusterfs.com> aka bzzz
13
 *  and Andreas Gruenbacher <agruen@suse.de>.
14
 */
15
 
16
/*
17
 * Extended attributes are stored directly in inodes (on file systems with
18
 * inodes bigger than 128 bytes) and on additional disk blocks. The i_file_acl
19
 * field contains the block number if an inode uses an additional block. All
20
 * attributes must fit in the inode and one additional block. Blocks that
21
 * contain the identical set of attributes may be shared among several inodes.
22
 * Identical blocks are detected by keeping a cache of blocks that have
23
 * recently been accessed.
24
 *
25
 * The attributes in inodes and on blocks have a different header; the entries
26
 * are stored in the same format:
27
 *
28
 *   +------------------+
29
 *   | header           |
30
 *   | entry 1          | |
31
 *   | entry 2          | | growing downwards
32
 *   | entry 3          | v
33
 *   | four null bytes  |
34
 *   | . . .            |
35
 *   | value 1          | ^
36
 *   | value 3          | | growing upwards
37
 *   | value 2          | |
38
 *   +------------------+
39
 *
40
 * The header is followed by multiple entry descriptors. In disk blocks, the
41
 * entry descriptors are kept sorted. In inodes, they are unsorted. The
42
 * attribute values are aligned to the end of the block in no specific order.
43
 *
44
 * Locking strategy
45
 * ----------------
46
 * EXT4_I(inode)->i_file_acl is protected by EXT4_I(inode)->xattr_sem.
47
 * EA blocks are only changed if they are exclusive to an inode, so
48
 * holding xattr_sem also means that nothing but the EA block's reference
49
 * count can change. Multiple writers to the same block are synchronized
50
 * by the buffer lock.
51
 */
52
 
53
#include <linux/init.h>
54
#include <linux/fs.h>
55
#include <linux/slab.h>
56
#include <linux/ext4_jbd2.h>
57
#include <linux/ext4_fs.h>
58
#include <linux/mbcache.h>
59
#include <linux/quotaops.h>
60
#include <linux/rwsem.h>
61
#include "xattr.h"
62
#include "acl.h"
63
 
64
#define BHDR(bh) ((struct ext4_xattr_header *)((bh)->b_data))
65
#define ENTRY(ptr) ((struct ext4_xattr_entry *)(ptr))
66
#define BFIRST(bh) ENTRY(BHDR(bh)+1)
67
#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
68
 
69
#ifdef EXT4_XATTR_DEBUG
70
# define ea_idebug(inode, f...) do { \
71
                printk(KERN_DEBUG "inode %s:%lu: ", \
72
                        inode->i_sb->s_id, inode->i_ino); \
73
                printk(f); \
74
                printk("\n"); \
75
        } while (0)
76
# define ea_bdebug(bh, f...) do { \
77
                char b[BDEVNAME_SIZE]; \
78
                printk(KERN_DEBUG "block %s:%lu: ", \
79
                        bdevname(bh->b_bdev, b), \
80
                        (unsigned long) bh->b_blocknr); \
81
                printk(f); \
82
                printk("\n"); \
83
        } while (0)
84
#else
85
# define ea_idebug(f...)
86
# define ea_bdebug(f...)
87
#endif
88
 
89
static void ext4_xattr_cache_insert(struct buffer_head *);
90
static struct buffer_head *ext4_xattr_cache_find(struct inode *,
91
                                                 struct ext4_xattr_header *,
92
                                                 struct mb_cache_entry **);
93
static void ext4_xattr_rehash(struct ext4_xattr_header *,
94
                              struct ext4_xattr_entry *);
95
 
96
static struct mb_cache *ext4_xattr_cache;
97
 
98
static struct xattr_handler *ext4_xattr_handler_map[] = {
99
        [EXT4_XATTR_INDEX_USER]              = &ext4_xattr_user_handler,
100
#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
101
        [EXT4_XATTR_INDEX_POSIX_ACL_ACCESS]  = &ext4_xattr_acl_access_handler,
102
        [EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT] = &ext4_xattr_acl_default_handler,
103
#endif
104
        [EXT4_XATTR_INDEX_TRUSTED]           = &ext4_xattr_trusted_handler,
105
#ifdef CONFIG_EXT4DEV_FS_SECURITY
106
        [EXT4_XATTR_INDEX_SECURITY]          = &ext4_xattr_security_handler,
107
#endif
108
};
109
 
110
struct xattr_handler *ext4_xattr_handlers[] = {
111
        &ext4_xattr_user_handler,
112
        &ext4_xattr_trusted_handler,
113
#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL
114
        &ext4_xattr_acl_access_handler,
115
        &ext4_xattr_acl_default_handler,
116
#endif
117
#ifdef CONFIG_EXT4DEV_FS_SECURITY
118
        &ext4_xattr_security_handler,
119
#endif
120
        NULL
121
};
122
 
123
static inline struct xattr_handler *
124
ext4_xattr_handler(int name_index)
125
{
126
        struct xattr_handler *handler = NULL;
127
 
128
        if (name_index > 0 && name_index < ARRAY_SIZE(ext4_xattr_handler_map))
129
                handler = ext4_xattr_handler_map[name_index];
130
        return handler;
131
}
132
 
133
/*
134
 * Inode operation listxattr()
135
 *
136
 * dentry->d_inode->i_mutex: don't care
137
 */
138
ssize_t
139
ext4_listxattr(struct dentry *dentry, char *buffer, size_t size)
140
{
141
        return ext4_xattr_list(dentry->d_inode, buffer, size);
142
}
143
 
144
static int
145
ext4_xattr_check_names(struct ext4_xattr_entry *entry, void *end)
146
{
147
        while (!IS_LAST_ENTRY(entry)) {
148
                struct ext4_xattr_entry *next = EXT4_XATTR_NEXT(entry);
149
                if ((void *)next >= end)
150
                        return -EIO;
151
                entry = next;
152
        }
153
        return 0;
154
}
155
 
156
static inline int
157
ext4_xattr_check_block(struct buffer_head *bh)
158
{
159
        int error;
160
 
161
        if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
162
            BHDR(bh)->h_blocks != cpu_to_le32(1))
163
                return -EIO;
164
        error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size);
165
        return error;
166
}
167
 
168
static inline int
169
ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
170
{
171
        size_t value_size = le32_to_cpu(entry->e_value_size);
172
 
173
        if (entry->e_value_block != 0 || value_size > size ||
174
            le16_to_cpu(entry->e_value_offs) + value_size > size)
175
                return -EIO;
176
        return 0;
177
}
178
 
179
static int
180
ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
181
                      const char *name, size_t size, int sorted)
182
{
183
        struct ext4_xattr_entry *entry;
184
        size_t name_len;
185
        int cmp = 1;
186
 
187
        if (name == NULL)
188
                return -EINVAL;
189
        name_len = strlen(name);
190
        entry = *pentry;
191
        for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
192
                cmp = name_index - entry->e_name_index;
193
                if (!cmp)
194
                        cmp = name_len - entry->e_name_len;
195
                if (!cmp)
196
                        cmp = memcmp(name, entry->e_name, name_len);
197
                if (cmp <= 0 && (sorted || cmp == 0))
198
                        break;
199
        }
200
        *pentry = entry;
201
        if (!cmp && ext4_xattr_check_entry(entry, size))
202
                        return -EIO;
203
        return cmp ? -ENODATA : 0;
204
}
205
 
206
static int
207
ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
208
                     void *buffer, size_t buffer_size)
209
{
210
        struct buffer_head *bh = NULL;
211
        struct ext4_xattr_entry *entry;
212
        size_t size;
213
        int error;
214
 
215
        ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld",
216
                  name_index, name, buffer, (long)buffer_size);
217
 
218
        error = -ENODATA;
219
        if (!EXT4_I(inode)->i_file_acl)
220
                goto cleanup;
221
        ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl);
222
        bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
223
        if (!bh)
224
                goto cleanup;
225
        ea_bdebug(bh, "b_count=%d, refcount=%d",
226
                atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
227
        if (ext4_xattr_check_block(bh)) {
228
bad_block:      ext4_error(inode->i_sb, __FUNCTION__,
229
                           "inode %lu: bad block %llu", inode->i_ino,
230
                           EXT4_I(inode)->i_file_acl);
231
                error = -EIO;
232
                goto cleanup;
233
        }
234
        ext4_xattr_cache_insert(bh);
235
        entry = BFIRST(bh);
236
        error = ext4_xattr_find_entry(&entry, name_index, name, bh->b_size, 1);
237
        if (error == -EIO)
238
                goto bad_block;
239
        if (error)
240
                goto cleanup;
241
        size = le32_to_cpu(entry->e_value_size);
242
        if (buffer) {
243
                error = -ERANGE;
244
                if (size > buffer_size)
245
                        goto cleanup;
246
                memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs),
247
                       size);
248
        }
249
        error = size;
250
 
251
cleanup:
252
        brelse(bh);
253
        return error;
254
}
255
 
256
static int
257
ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
258
                     void *buffer, size_t buffer_size)
259
{
260
        struct ext4_xattr_ibody_header *header;
261
        struct ext4_xattr_entry *entry;
262
        struct ext4_inode *raw_inode;
263
        struct ext4_iloc iloc;
264
        size_t size;
265
        void *end;
266
        int error;
267
 
268
        if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR))
269
                return -ENODATA;
270
        error = ext4_get_inode_loc(inode, &iloc);
271
        if (error)
272
                return error;
273
        raw_inode = ext4_raw_inode(&iloc);
274
        header = IHDR(inode, raw_inode);
275
        entry = IFIRST(header);
276
        end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
277
        error = ext4_xattr_check_names(entry, end);
278
        if (error)
279
                goto cleanup;
280
        error = ext4_xattr_find_entry(&entry, name_index, name,
281
                                      end - (void *)entry, 0);
282
        if (error)
283
                goto cleanup;
284
        size = le32_to_cpu(entry->e_value_size);
285
        if (buffer) {
286
                error = -ERANGE;
287
                if (size > buffer_size)
288
                        goto cleanup;
289
                memcpy(buffer, (void *)IFIRST(header) +
290
                       le16_to_cpu(entry->e_value_offs), size);
291
        }
292
        error = size;
293
 
294
cleanup:
295
        brelse(iloc.bh);
296
        return error;
297
}
298
 
299
/*
300
 * ext4_xattr_get()
301
 *
302
 * Copy an extended attribute into the buffer
303
 * provided, or compute the buffer size required.
304
 * Buffer is NULL to compute the size of the buffer required.
305
 *
306
 * Returns a negative error number on failure, or the number of bytes
307
 * used / required on success.
308
 */
309
int
310
ext4_xattr_get(struct inode *inode, int name_index, const char *name,
311
               void *buffer, size_t buffer_size)
312
{
313
        int error;
314
 
315
        down_read(&EXT4_I(inode)->xattr_sem);
316
        error = ext4_xattr_ibody_get(inode, name_index, name, buffer,
317
                                     buffer_size);
318
        if (error == -ENODATA)
319
                error = ext4_xattr_block_get(inode, name_index, name, buffer,
320
                                             buffer_size);
321
        up_read(&EXT4_I(inode)->xattr_sem);
322
        return error;
323
}
324
 
325
static int
326
ext4_xattr_list_entries(struct inode *inode, struct ext4_xattr_entry *entry,
327
                        char *buffer, size_t buffer_size)
328
{
329
        size_t rest = buffer_size;
330
 
331
        for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) {
332
                struct xattr_handler *handler =
333
                        ext4_xattr_handler(entry->e_name_index);
334
 
335
                if (handler) {
336
                        size_t size = handler->list(inode, buffer, rest,
337
                                                    entry->e_name,
338
                                                    entry->e_name_len);
339
                        if (buffer) {
340
                                if (size > rest)
341
                                        return -ERANGE;
342
                                buffer += size;
343
                        }
344
                        rest -= size;
345
                }
346
        }
347
        return buffer_size - rest;
348
}
349
 
350
static int
351
ext4_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
352
{
353
        struct buffer_head *bh = NULL;
354
        int error;
355
 
356
        ea_idebug(inode, "buffer=%p, buffer_size=%ld",
357
                  buffer, (long)buffer_size);
358
 
359
        error = 0;
360
        if (!EXT4_I(inode)->i_file_acl)
361
                goto cleanup;
362
        ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl);
363
        bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
364
        error = -EIO;
365
        if (!bh)
366
                goto cleanup;
367
        ea_bdebug(bh, "b_count=%d, refcount=%d",
368
                atomic_read(&(bh->b_count)), le32_to_cpu(BHDR(bh)->h_refcount));
369
        if (ext4_xattr_check_block(bh)) {
370
                ext4_error(inode->i_sb, __FUNCTION__,
371
                           "inode %lu: bad block %llu", inode->i_ino,
372
                           EXT4_I(inode)->i_file_acl);
373
                error = -EIO;
374
                goto cleanup;
375
        }
376
        ext4_xattr_cache_insert(bh);
377
        error = ext4_xattr_list_entries(inode, BFIRST(bh), buffer, buffer_size);
378
 
379
cleanup:
380
        brelse(bh);
381
 
382
        return error;
383
}
384
 
385
static int
386
ext4_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
387
{
388
        struct ext4_xattr_ibody_header *header;
389
        struct ext4_inode *raw_inode;
390
        struct ext4_iloc iloc;
391
        void *end;
392
        int error;
393
 
394
        if (!(EXT4_I(inode)->i_state & EXT4_STATE_XATTR))
395
                return 0;
396
        error = ext4_get_inode_loc(inode, &iloc);
397
        if (error)
398
                return error;
399
        raw_inode = ext4_raw_inode(&iloc);
400
        header = IHDR(inode, raw_inode);
401
        end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
402
        error = ext4_xattr_check_names(IFIRST(header), end);
403
        if (error)
404
                goto cleanup;
405
        error = ext4_xattr_list_entries(inode, IFIRST(header),
406
                                        buffer, buffer_size);
407
 
408
cleanup:
409
        brelse(iloc.bh);
410
        return error;
411
}
412
 
413
/*
414
 * ext4_xattr_list()
415
 *
416
 * Copy a list of attribute names into the buffer
417
 * provided, or compute the buffer size required.
418
 * Buffer is NULL to compute the size of the buffer required.
419
 *
420
 * Returns a negative error number on failure, or the number of bytes
421
 * used / required on success.
422
 */
423
int
424
ext4_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
425
{
426
        int i_error, b_error;
427
 
428
        down_read(&EXT4_I(inode)->xattr_sem);
429
        i_error = ext4_xattr_ibody_list(inode, buffer, buffer_size);
430
        if (i_error < 0) {
431
                b_error = 0;
432
        } else {
433
                if (buffer) {
434
                        buffer += i_error;
435
                        buffer_size -= i_error;
436
                }
437
                b_error = ext4_xattr_block_list(inode, buffer, buffer_size);
438
                if (b_error < 0)
439
                        i_error = 0;
440
        }
441
        up_read(&EXT4_I(inode)->xattr_sem);
442
        return i_error + b_error;
443
}
444
 
445
/*
446
 * If the EXT4_FEATURE_COMPAT_EXT_ATTR feature of this file system is
447
 * not set, set it.
448
 */
449
static void ext4_xattr_update_super_block(handle_t *handle,
450
                                          struct super_block *sb)
451
{
452
        if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR))
453
                return;
454
 
455
        if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) {
456
                EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR);
457
                sb->s_dirt = 1;
458
                ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
459
        }
460
}
461
 
462
/*
463
 * Release the xattr block BH: If the reference count is > 1, decrement
464
 * it; otherwise free the block.
465
 */
466
static void
467
ext4_xattr_release_block(handle_t *handle, struct inode *inode,
468
                         struct buffer_head *bh)
469
{
470
        struct mb_cache_entry *ce = NULL;
471
        int error = 0;
472
 
473
        ce = mb_cache_entry_get(ext4_xattr_cache, bh->b_bdev, bh->b_blocknr);
474
        error = ext4_journal_get_write_access(handle, bh);
475
        if (error)
476
                goto out;
477
 
478
        lock_buffer(bh);
479
        if (BHDR(bh)->h_refcount == cpu_to_le32(1)) {
480
                ea_bdebug(bh, "refcount now=0; freeing");
481
                if (ce)
482
                        mb_cache_entry_free(ce);
483
                ext4_free_blocks(handle, inode, bh->b_blocknr, 1);
484
                get_bh(bh);
485
                ext4_forget(handle, 1, inode, bh, bh->b_blocknr);
486
        } else {
487
                BHDR(bh)->h_refcount = cpu_to_le32(
488
                                le32_to_cpu(BHDR(bh)->h_refcount) - 1);
489
                error = ext4_journal_dirty_metadata(handle, bh);
490
                if (IS_SYNC(inode))
491
                        handle->h_sync = 1;
492
                DQUOT_FREE_BLOCK(inode, 1);
493
                ea_bdebug(bh, "refcount now=%d; releasing",
494
                          le32_to_cpu(BHDR(bh)->h_refcount));
495
                if (ce)
496
                        mb_cache_entry_release(ce);
497
        }
498
        unlock_buffer(bh);
499
out:
500
        ext4_std_error(inode->i_sb, error);
501
        return;
502
}
503
 
504
/*
505
 * Find the available free space for EAs. This also returns the total number of
506
 * bytes used by EA entries.
507
 */
508
static size_t ext4_xattr_free_space(struct ext4_xattr_entry *last,
509
                                    size_t *min_offs, void *base, int *total)
510
{
511
        for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
512
                *total += EXT4_XATTR_LEN(last->e_name_len);
513
                if (!last->e_value_block && last->e_value_size) {
514
                        size_t offs = le16_to_cpu(last->e_value_offs);
515
                        if (offs < *min_offs)
516
                                *min_offs = offs;
517
                }
518
        }
519
        return (*min_offs - ((void *)last - base) - sizeof(__u32));
520
}
521
 
522
struct ext4_xattr_info {
523
        int name_index;
524
        const char *name;
525
        const void *value;
526
        size_t value_len;
527
};
528
 
529
struct ext4_xattr_search {
530
        struct ext4_xattr_entry *first;
531
        void *base;
532
        void *end;
533
        struct ext4_xattr_entry *here;
534
        int not_found;
535
};
536
 
537
static int
538
ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s)
539
{
540
        struct ext4_xattr_entry *last;
541
        size_t free, min_offs = s->end - s->base, name_len = strlen(i->name);
542
 
543
        /* Compute min_offs and last. */
544
        last = s->first;
545
        for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
546
                if (!last->e_value_block && last->e_value_size) {
547
                        size_t offs = le16_to_cpu(last->e_value_offs);
548
                        if (offs < min_offs)
549
                                min_offs = offs;
550
                }
551
        }
552
        free = min_offs - ((void *)last - s->base) - sizeof(__u32);
553
        if (!s->not_found) {
554
                if (!s->here->e_value_block && s->here->e_value_size) {
555
                        size_t size = le32_to_cpu(s->here->e_value_size);
556
                        free += EXT4_XATTR_SIZE(size);
557
                }
558
                free += EXT4_XATTR_LEN(name_len);
559
        }
560
        if (i->value) {
561
                if (free < EXT4_XATTR_SIZE(i->value_len) ||
562
                    free < EXT4_XATTR_LEN(name_len) +
563
                           EXT4_XATTR_SIZE(i->value_len))
564
                        return -ENOSPC;
565
        }
566
 
567
        if (i->value && s->not_found) {
568
                /* Insert the new name. */
569
                size_t size = EXT4_XATTR_LEN(name_len);
570
                size_t rest = (void *)last - (void *)s->here + sizeof(__u32);
571
                memmove((void *)s->here + size, s->here, rest);
572
                memset(s->here, 0, size);
573
                s->here->e_name_index = i->name_index;
574
                s->here->e_name_len = name_len;
575
                memcpy(s->here->e_name, i->name, name_len);
576
        } else {
577
                if (!s->here->e_value_block && s->here->e_value_size) {
578
                        void *first_val = s->base + min_offs;
579
                        size_t offs = le16_to_cpu(s->here->e_value_offs);
580
                        void *val = s->base + offs;
581
                        size_t size = EXT4_XATTR_SIZE(
582
                                le32_to_cpu(s->here->e_value_size));
583
 
584
                        if (i->value && size == EXT4_XATTR_SIZE(i->value_len)) {
585
                                /* The old and the new value have the same
586
                                   size. Just replace. */
587
                                s->here->e_value_size =
588
                                        cpu_to_le32(i->value_len);
589
                                memset(val + size - EXT4_XATTR_PAD, 0,
590
                                       EXT4_XATTR_PAD); /* Clear pad bytes. */
591
                                memcpy(val, i->value, i->value_len);
592
                                return 0;
593
                        }
594
 
595
                        /* Remove the old value. */
596
                        memmove(first_val + size, first_val, val - first_val);
597
                        memset(first_val, 0, size);
598
                        s->here->e_value_size = 0;
599
                        s->here->e_value_offs = 0;
600
                        min_offs += size;
601
 
602
                        /* Adjust all value offsets. */
603
                        last = s->first;
604
                        while (!IS_LAST_ENTRY(last)) {
605
                                size_t o = le16_to_cpu(last->e_value_offs);
606
                                if (!last->e_value_block &&
607
                                    last->e_value_size && o < offs)
608
                                        last->e_value_offs =
609
                                                cpu_to_le16(o + size);
610
                                last = EXT4_XATTR_NEXT(last);
611
                        }
612
                }
613
                if (!i->value) {
614
                        /* Remove the old name. */
615
                        size_t size = EXT4_XATTR_LEN(name_len);
616
                        last = ENTRY((void *)last - size);
617
                        memmove(s->here, (void *)s->here + size,
618
                                (void *)last - (void *)s->here + sizeof(__u32));
619
                        memset(last, 0, size);
620
                }
621
        }
622
 
623
        if (i->value) {
624
                /* Insert the new value. */
625
                s->here->e_value_size = cpu_to_le32(i->value_len);
626
                if (i->value_len) {
627
                        size_t size = EXT4_XATTR_SIZE(i->value_len);
628
                        void *val = s->base + min_offs - size;
629
                        s->here->e_value_offs = cpu_to_le16(min_offs - size);
630
                        memset(val + size - EXT4_XATTR_PAD, 0,
631
                               EXT4_XATTR_PAD); /* Clear the pad bytes. */
632
                        memcpy(val, i->value, i->value_len);
633
                }
634
        }
635
        return 0;
636
}
637
 
638
struct ext4_xattr_block_find {
639
        struct ext4_xattr_search s;
640
        struct buffer_head *bh;
641
};
642
 
643
static int
644
ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
645
                      struct ext4_xattr_block_find *bs)
646
{
647
        struct super_block *sb = inode->i_sb;
648
        int error;
649
 
650
        ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
651
                  i->name_index, i->name, i->value, (long)i->value_len);
652
 
653
        if (EXT4_I(inode)->i_file_acl) {
654
                /* The inode already has an extended attribute block. */
655
                bs->bh = sb_bread(sb, EXT4_I(inode)->i_file_acl);
656
                error = -EIO;
657
                if (!bs->bh)
658
                        goto cleanup;
659
                ea_bdebug(bs->bh, "b_count=%d, refcount=%d",
660
                        atomic_read(&(bs->bh->b_count)),
661
                        le32_to_cpu(BHDR(bs->bh)->h_refcount));
662
                if (ext4_xattr_check_block(bs->bh)) {
663
                        ext4_error(sb, __FUNCTION__,
664
                                "inode %lu: bad block %llu", inode->i_ino,
665
                                EXT4_I(inode)->i_file_acl);
666
                        error = -EIO;
667
                        goto cleanup;
668
                }
669
                /* Find the named attribute. */
670
                bs->s.base = BHDR(bs->bh);
671
                bs->s.first = BFIRST(bs->bh);
672
                bs->s.end = bs->bh->b_data + bs->bh->b_size;
673
                bs->s.here = bs->s.first;
674
                error = ext4_xattr_find_entry(&bs->s.here, i->name_index,
675
                                              i->name, bs->bh->b_size, 1);
676
                if (error && error != -ENODATA)
677
                        goto cleanup;
678
                bs->s.not_found = error;
679
        }
680
        error = 0;
681
 
682
cleanup:
683
        return error;
684
}
685
 
686
static int
687
ext4_xattr_block_set(handle_t *handle, struct inode *inode,
688
                     struct ext4_xattr_info *i,
689
                     struct ext4_xattr_block_find *bs)
690
{
691
        struct super_block *sb = inode->i_sb;
692
        struct buffer_head *new_bh = NULL;
693
        struct ext4_xattr_search *s = &bs->s;
694
        struct mb_cache_entry *ce = NULL;
695
        int error = 0;
696
 
697
#define header(x) ((struct ext4_xattr_header *)(x))
698
 
699
        if (i->value && i->value_len > sb->s_blocksize)
700
                return -ENOSPC;
701
        if (s->base) {
702
                ce = mb_cache_entry_get(ext4_xattr_cache, bs->bh->b_bdev,
703
                                        bs->bh->b_blocknr);
704
                error = ext4_journal_get_write_access(handle, bs->bh);
705
                if (error)
706
                        goto cleanup;
707
                lock_buffer(bs->bh);
708
 
709
                if (header(s->base)->h_refcount == cpu_to_le32(1)) {
710
                        if (ce) {
711
                                mb_cache_entry_free(ce);
712
                                ce = NULL;
713
                        }
714
                        ea_bdebug(bs->bh, "modifying in-place");
715
                        error = ext4_xattr_set_entry(i, s);
716
                        if (!error) {
717
                                if (!IS_LAST_ENTRY(s->first))
718
                                        ext4_xattr_rehash(header(s->base),
719
                                                          s->here);
720
                                ext4_xattr_cache_insert(bs->bh);
721
                        }
722
                        unlock_buffer(bs->bh);
723
                        if (error == -EIO)
724
                                goto bad_block;
725
                        if (!error)
726
                                error = ext4_journal_dirty_metadata(handle,
727
                                                                    bs->bh);
728
                        if (error)
729
                                goto cleanup;
730
                        goto inserted;
731
                } else {
732
                        int offset = (char *)s->here - bs->bh->b_data;
733
 
734
                        unlock_buffer(bs->bh);
735
                        jbd2_journal_release_buffer(handle, bs->bh);
736
                        if (ce) {
737
                                mb_cache_entry_release(ce);
738
                                ce = NULL;
739
                        }
740
                        ea_bdebug(bs->bh, "cloning");
741
                        s->base = kmalloc(bs->bh->b_size, GFP_KERNEL);
742
                        error = -ENOMEM;
743
                        if (s->base == NULL)
744
                                goto cleanup;
745
                        memcpy(s->base, BHDR(bs->bh), bs->bh->b_size);
746
                        s->first = ENTRY(header(s->base)+1);
747
                        header(s->base)->h_refcount = cpu_to_le32(1);
748
                        s->here = ENTRY(s->base + offset);
749
                        s->end = s->base + bs->bh->b_size;
750
                }
751
        } else {
752
                /* Allocate a buffer where we construct the new block. */
753
                s->base = kzalloc(sb->s_blocksize, GFP_KERNEL);
754
                /* assert(header == s->base) */
755
                error = -ENOMEM;
756
                if (s->base == NULL)
757
                        goto cleanup;
758
                header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
759
                header(s->base)->h_blocks = cpu_to_le32(1);
760
                header(s->base)->h_refcount = cpu_to_le32(1);
761
                s->first = ENTRY(header(s->base)+1);
762
                s->here = ENTRY(header(s->base)+1);
763
                s->end = s->base + sb->s_blocksize;
764
        }
765
 
766
        error = ext4_xattr_set_entry(i, s);
767
        if (error == -EIO)
768
                goto bad_block;
769
        if (error)
770
                goto cleanup;
771
        if (!IS_LAST_ENTRY(s->first))
772
                ext4_xattr_rehash(header(s->base), s->here);
773
 
774
inserted:
775
        if (!IS_LAST_ENTRY(s->first)) {
776
                new_bh = ext4_xattr_cache_find(inode, header(s->base), &ce);
777
                if (new_bh) {
778
                        /* We found an identical block in the cache. */
779
                        if (new_bh == bs->bh)
780
                                ea_bdebug(new_bh, "keeping");
781
                        else {
782
                                /* The old block is released after updating
783
                                   the inode. */
784
                                error = -EDQUOT;
785
                                if (DQUOT_ALLOC_BLOCK(inode, 1))
786
                                        goto cleanup;
787
                                error = ext4_journal_get_write_access(handle,
788
                                                                      new_bh);
789
                                if (error)
790
                                        goto cleanup_dquot;
791
                                lock_buffer(new_bh);
792
                                BHDR(new_bh)->h_refcount = cpu_to_le32(1 +
793
                                        le32_to_cpu(BHDR(new_bh)->h_refcount));
794
                                ea_bdebug(new_bh, "reusing; refcount now=%d",
795
                                        le32_to_cpu(BHDR(new_bh)->h_refcount));
796
                                unlock_buffer(new_bh);
797
                                error = ext4_journal_dirty_metadata(handle,
798
                                                                    new_bh);
799
                                if (error)
800
                                        goto cleanup_dquot;
801
                        }
802
                        mb_cache_entry_release(ce);
803
                        ce = NULL;
804
                } else if (bs->bh && s->base == bs->bh->b_data) {
805
                        /* We were modifying this block in-place. */
806
                        ea_bdebug(bs->bh, "keeping this block");
807
                        new_bh = bs->bh;
808
                        get_bh(new_bh);
809
                } else {
810
                        /* We need to allocate a new block */
811
                        ext4_fsblk_t goal = le32_to_cpu(
812
                                        EXT4_SB(sb)->s_es->s_first_data_block) +
813
                                (ext4_fsblk_t)EXT4_I(inode)->i_block_group *
814
                                EXT4_BLOCKS_PER_GROUP(sb);
815
                        ext4_fsblk_t block = ext4_new_block(handle, inode,
816
                                                        goal, &error);
817
                        if (error)
818
                                goto cleanup;
819
                        ea_idebug(inode, "creating block %d", block);
820
 
821
                        new_bh = sb_getblk(sb, block);
822
                        if (!new_bh) {
823
getblk_failed:
824
                                ext4_free_blocks(handle, inode, block, 1);
825
                                error = -EIO;
826
                                goto cleanup;
827
                        }
828
                        lock_buffer(new_bh);
829
                        error = ext4_journal_get_create_access(handle, new_bh);
830
                        if (error) {
831
                                unlock_buffer(new_bh);
832
                                goto getblk_failed;
833
                        }
834
                        memcpy(new_bh->b_data, s->base, new_bh->b_size);
835
                        set_buffer_uptodate(new_bh);
836
                        unlock_buffer(new_bh);
837
                        ext4_xattr_cache_insert(new_bh);
838
                        error = ext4_journal_dirty_metadata(handle, new_bh);
839
                        if (error)
840
                                goto cleanup;
841
                }
842
        }
843
 
844
        /* Update the inode. */
845
        EXT4_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
846
 
847
        /* Drop the previous xattr block. */
848
        if (bs->bh && bs->bh != new_bh)
849
                ext4_xattr_release_block(handle, inode, bs->bh);
850
        error = 0;
851
 
852
cleanup:
853
        if (ce)
854
                mb_cache_entry_release(ce);
855
        brelse(new_bh);
856
        if (!(bs->bh && s->base == bs->bh->b_data))
857
                kfree(s->base);
858
 
859
        return error;
860
 
861
cleanup_dquot:
862
        DQUOT_FREE_BLOCK(inode, 1);
863
        goto cleanup;
864
 
865
bad_block:
866
        ext4_error(inode->i_sb, __FUNCTION__,
867
                   "inode %lu: bad block %llu", inode->i_ino,
868
                   EXT4_I(inode)->i_file_acl);
869
        goto cleanup;
870
 
871
#undef header
872
}
873
 
874
struct ext4_xattr_ibody_find {
875
        struct ext4_xattr_search s;
876
        struct ext4_iloc iloc;
877
};
878
 
879
static int
880
ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
881
                      struct ext4_xattr_ibody_find *is)
882
{
883
        struct ext4_xattr_ibody_header *header;
884
        struct ext4_inode *raw_inode;
885
        int error;
886
 
887
        if (EXT4_I(inode)->i_extra_isize == 0)
888
                return 0;
889
        raw_inode = ext4_raw_inode(&is->iloc);
890
        header = IHDR(inode, raw_inode);
891
        is->s.base = is->s.first = IFIRST(header);
892
        is->s.here = is->s.first;
893
        is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
894
        if (EXT4_I(inode)->i_state & EXT4_STATE_XATTR) {
895
                error = ext4_xattr_check_names(IFIRST(header), is->s.end);
896
                if (error)
897
                        return error;
898
                /* Find the named attribute. */
899
                error = ext4_xattr_find_entry(&is->s.here, i->name_index,
900
                                              i->name, is->s.end -
901
                                              (void *)is->s.base, 0);
902
                if (error && error != -ENODATA)
903
                        return error;
904
                is->s.not_found = error;
905
        }
906
        return 0;
907
}
908
 
909
static int
910
ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
911
                     struct ext4_xattr_info *i,
912
                     struct ext4_xattr_ibody_find *is)
913
{
914
        struct ext4_xattr_ibody_header *header;
915
        struct ext4_xattr_search *s = &is->s;
916
        int error;
917
 
918
        if (EXT4_I(inode)->i_extra_isize == 0)
919
                return -ENOSPC;
920
        error = ext4_xattr_set_entry(i, s);
921
        if (error)
922
                return error;
923
        header = IHDR(inode, ext4_raw_inode(&is->iloc));
924
        if (!IS_LAST_ENTRY(s->first)) {
925
                header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
926
                EXT4_I(inode)->i_state |= EXT4_STATE_XATTR;
927
        } else {
928
                header->h_magic = cpu_to_le32(0);
929
                EXT4_I(inode)->i_state &= ~EXT4_STATE_XATTR;
930
        }
931
        return 0;
932
}
933
 
934
/*
935
 * ext4_xattr_set_handle()
936
 *
937
 * Create, replace or remove an extended attribute for this inode. Buffer
938
 * is NULL to remove an existing extended attribute, and non-NULL to
939
 * either replace an existing extended attribute, or create a new extended
940
 * attribute. The flags XATTR_REPLACE and XATTR_CREATE
941
 * specify that an extended attribute must exist and must not exist
942
 * previous to the call, respectively.
943
 *
944
 * Returns 0, or a negative error number on failure.
945
 */
946
int
947
ext4_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
948
                      const char *name, const void *value, size_t value_len,
949
                      int flags)
950
{
951
        struct ext4_xattr_info i = {
952
                .name_index = name_index,
953
                .name = name,
954
                .value = value,
955
                .value_len = value_len,
956
 
957
        };
958
        struct ext4_xattr_ibody_find is = {
959
                .s = { .not_found = -ENODATA, },
960
        };
961
        struct ext4_xattr_block_find bs = {
962
                .s = { .not_found = -ENODATA, },
963
        };
964
        int error;
965
 
966
        if (!name)
967
                return -EINVAL;
968
        if (strlen(name) > 255)
969
                return -ERANGE;
970
        down_write(&EXT4_I(inode)->xattr_sem);
971
        error = ext4_get_inode_loc(inode, &is.iloc);
972
        if (error)
973
                goto cleanup;
974
 
975
        if (EXT4_I(inode)->i_state & EXT4_STATE_NEW) {
976
                struct ext4_inode *raw_inode = ext4_raw_inode(&is.iloc);
977
                memset(raw_inode, 0, EXT4_SB(inode->i_sb)->s_inode_size);
978
                EXT4_I(inode)->i_state &= ~EXT4_STATE_NEW;
979
        }
980
 
981
        error = ext4_xattr_ibody_find(inode, &i, &is);
982
        if (error)
983
                goto cleanup;
984
        if (is.s.not_found)
985
                error = ext4_xattr_block_find(inode, &i, &bs);
986
        if (error)
987
                goto cleanup;
988
        if (is.s.not_found && bs.s.not_found) {
989
                error = -ENODATA;
990
                if (flags & XATTR_REPLACE)
991
                        goto cleanup;
992
                error = 0;
993
                if (!value)
994
                        goto cleanup;
995
        } else {
996
                error = -EEXIST;
997
                if (flags & XATTR_CREATE)
998
                        goto cleanup;
999
        }
1000
        error = ext4_journal_get_write_access(handle, is.iloc.bh);
1001
        if (error)
1002
                goto cleanup;
1003
        if (!value) {
1004
                if (!is.s.not_found)
1005
                        error = ext4_xattr_ibody_set(handle, inode, &i, &is);
1006
                else if (!bs.s.not_found)
1007
                        error = ext4_xattr_block_set(handle, inode, &i, &bs);
1008
        } else {
1009
                error = ext4_xattr_ibody_set(handle, inode, &i, &is);
1010
                if (!error && !bs.s.not_found) {
1011
                        i.value = NULL;
1012
                        error = ext4_xattr_block_set(handle, inode, &i, &bs);
1013
                } else if (error == -ENOSPC) {
1014
                        error = ext4_xattr_block_set(handle, inode, &i, &bs);
1015
                        if (error)
1016
                                goto cleanup;
1017
                        if (!is.s.not_found) {
1018
                                i.value = NULL;
1019
                                error = ext4_xattr_ibody_set(handle, inode, &i,
1020
                                                             &is);
1021
                        }
1022
                }
1023
        }
1024
        if (!error) {
1025
                ext4_xattr_update_super_block(handle, inode->i_sb);
1026
                inode->i_ctime = ext4_current_time(inode);
1027
                if (!value)
1028
                        EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND;
1029
                error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
1030
                /*
1031
                 * The bh is consumed by ext4_mark_iloc_dirty, even with
1032
                 * error != 0.
1033
                 */
1034
                is.iloc.bh = NULL;
1035
                if (IS_SYNC(inode))
1036
                        handle->h_sync = 1;
1037
        }
1038
 
1039
cleanup:
1040
        brelse(is.iloc.bh);
1041
        brelse(bs.bh);
1042
        up_write(&EXT4_I(inode)->xattr_sem);
1043
        return error;
1044
}
1045
 
1046
/*
1047
 * ext4_xattr_set()
1048
 *
1049
 * Like ext4_xattr_set_handle, but start from an inode. This extended
1050
 * attribute modification is a filesystem transaction by itself.
1051
 *
1052
 * Returns 0, or a negative error number on failure.
1053
 */
1054
int
1055
ext4_xattr_set(struct inode *inode, int name_index, const char *name,
1056
               const void *value, size_t value_len, int flags)
1057
{
1058
        handle_t *handle;
1059
        int error, retries = 0;
1060
 
1061
retry:
1062
        handle = ext4_journal_start(inode, EXT4_DATA_TRANS_BLOCKS(inode->i_sb));
1063
        if (IS_ERR(handle)) {
1064
                error = PTR_ERR(handle);
1065
        } else {
1066
                int error2;
1067
 
1068
                error = ext4_xattr_set_handle(handle, inode, name_index, name,
1069
                                              value, value_len, flags);
1070
                error2 = ext4_journal_stop(handle);
1071
                if (error == -ENOSPC &&
1072
                    ext4_should_retry_alloc(inode->i_sb, &retries))
1073
                        goto retry;
1074
                if (error == 0)
1075
                        error = error2;
1076
        }
1077
 
1078
        return error;
1079
}
1080
 
1081
/*
1082
 * Shift the EA entries in the inode to create space for the increased
1083
 * i_extra_isize.
1084
 */
1085
static void ext4_xattr_shift_entries(struct ext4_xattr_entry *entry,
1086
                                     int value_offs_shift, void *to,
1087
                                     void *from, size_t n, int blocksize)
1088
{
1089
        struct ext4_xattr_entry *last = entry;
1090
        int new_offs;
1091
 
1092
        /* Adjust the value offsets of the entries */
1093
        for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
1094
                if (!last->e_value_block && last->e_value_size) {
1095
                        new_offs = le16_to_cpu(last->e_value_offs) +
1096
                                                        value_offs_shift;
1097
                        BUG_ON(new_offs + le32_to_cpu(last->e_value_size)
1098
                                 > blocksize);
1099
                        last->e_value_offs = cpu_to_le16(new_offs);
1100
                }
1101
        }
1102
        /* Shift the entries by n bytes */
1103
        memmove(to, from, n);
1104
}
1105
 
1106
/*
1107
 * Expand an inode by new_extra_isize bytes when EAs are present.
1108
 * Returns 0 on success or negative error number on failure.
1109
 */
1110
int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
1111
                               struct ext4_inode *raw_inode, handle_t *handle)
1112
{
1113
        struct ext4_xattr_ibody_header *header;
1114
        struct ext4_xattr_entry *entry, *last, *first;
1115
        struct buffer_head *bh = NULL;
1116
        struct ext4_xattr_ibody_find *is = NULL;
1117
        struct ext4_xattr_block_find *bs = NULL;
1118
        char *buffer = NULL, *b_entry_name = NULL;
1119
        size_t min_offs, free;
1120
        int total_ino, total_blk;
1121
        void *base, *start, *end;
1122
        int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
1123
        int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
1124
 
1125
        down_write(&EXT4_I(inode)->xattr_sem);
1126
retry:
1127
        if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
1128
                up_write(&EXT4_I(inode)->xattr_sem);
1129
                return 0;
1130
        }
1131
 
1132
        header = IHDR(inode, raw_inode);
1133
        entry = IFIRST(header);
1134
 
1135
        /*
1136
         * Check if enough free space is available in the inode to shift the
1137
         * entries ahead by new_extra_isize.
1138
         */
1139
 
1140
        base = start = entry;
1141
        end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
1142
        min_offs = end - base;
1143
        last = entry;
1144
        total_ino = sizeof(struct ext4_xattr_ibody_header);
1145
 
1146
        free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
1147
        if (free >= new_extra_isize) {
1148
                entry = IFIRST(header);
1149
                ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize
1150
                                - new_extra_isize, (void *)raw_inode +
1151
                                EXT4_GOOD_OLD_INODE_SIZE + new_extra_isize,
1152
                                (void *)header, total_ino,
1153
                                inode->i_sb->s_blocksize);
1154
                EXT4_I(inode)->i_extra_isize = new_extra_isize;
1155
                error = 0;
1156
                goto cleanup;
1157
        }
1158
 
1159
        /*
1160
         * Enough free space isn't available in the inode, check if
1161
         * EA block can hold new_extra_isize bytes.
1162
         */
1163
        if (EXT4_I(inode)->i_file_acl) {
1164
                bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
1165
                error = -EIO;
1166
                if (!bh)
1167
                        goto cleanup;
1168
                if (ext4_xattr_check_block(bh)) {
1169
                        ext4_error(inode->i_sb, __FUNCTION__,
1170
                                "inode %lu: bad block %llu", inode->i_ino,
1171
                                EXT4_I(inode)->i_file_acl);
1172
                        error = -EIO;
1173
                        goto cleanup;
1174
                }
1175
                base = BHDR(bh);
1176
                first = BFIRST(bh);
1177
                end = bh->b_data + bh->b_size;
1178
                min_offs = end - base;
1179
                free = ext4_xattr_free_space(first, &min_offs, base,
1180
                                             &total_blk);
1181
                if (free < new_extra_isize) {
1182
                        if (!tried_min_extra_isize && s_min_extra_isize) {
1183
                                tried_min_extra_isize++;
1184
                                new_extra_isize = s_min_extra_isize;
1185
                                brelse(bh);
1186
                                goto retry;
1187
                        }
1188
                        error = -1;
1189
                        goto cleanup;
1190
                }
1191
        } else {
1192
                free = inode->i_sb->s_blocksize;
1193
        }
1194
 
1195
        while (new_extra_isize > 0) {
1196
                size_t offs, size, entry_size;
1197
                struct ext4_xattr_entry *small_entry = NULL;
1198
                struct ext4_xattr_info i = {
1199
                        .value = NULL,
1200
                        .value_len = 0,
1201
                };
1202
                unsigned int total_size;  /* EA entry size + value size */
1203
                unsigned int shift_bytes; /* No. of bytes to shift EAs by? */
1204
                unsigned int min_total_size = ~0U;
1205
 
1206
                is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS);
1207
                bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS);
1208
                if (!is || !bs) {
1209
                        error = -ENOMEM;
1210
                        goto cleanup;
1211
                }
1212
 
1213
                is->s.not_found = -ENODATA;
1214
                bs->s.not_found = -ENODATA;
1215
                is->iloc.bh = NULL;
1216
                bs->bh = NULL;
1217
 
1218
                last = IFIRST(header);
1219
                /* Find the entry best suited to be pushed into EA block */
1220
                entry = NULL;
1221
                for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
1222
                        total_size =
1223
                        EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
1224
                                        EXT4_XATTR_LEN(last->e_name_len);
1225
                        if (total_size <= free && total_size < min_total_size) {
1226
                                if (total_size < new_extra_isize) {
1227
                                        small_entry = last;
1228
                                } else {
1229
                                        entry = last;
1230
                                        min_total_size = total_size;
1231
                                }
1232
                        }
1233
                }
1234
 
1235
                if (entry == NULL) {
1236
                        if (small_entry) {
1237
                                entry = small_entry;
1238
                        } else {
1239
                                if (!tried_min_extra_isize &&
1240
                                    s_min_extra_isize) {
1241
                                        tried_min_extra_isize++;
1242
                                        new_extra_isize = s_min_extra_isize;
1243
                                        goto retry;
1244
                                }
1245
                                error = -1;
1246
                                goto cleanup;
1247
                        }
1248
                }
1249
                offs = le16_to_cpu(entry->e_value_offs);
1250
                size = le32_to_cpu(entry->e_value_size);
1251
                entry_size = EXT4_XATTR_LEN(entry->e_name_len);
1252
                i.name_index = entry->e_name_index,
1253
                buffer = kmalloc(EXT4_XATTR_SIZE(size), GFP_NOFS);
1254
                b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS);
1255
                if (!buffer || !b_entry_name) {
1256
                        error = -ENOMEM;
1257
                        goto cleanup;
1258
                }
1259
                /* Save the entry name and the entry value */
1260
                memcpy(buffer, (void *)IFIRST(header) + offs,
1261
                       EXT4_XATTR_SIZE(size));
1262
                memcpy(b_entry_name, entry->e_name, entry->e_name_len);
1263
                b_entry_name[entry->e_name_len] = '\0';
1264
                i.name = b_entry_name;
1265
 
1266
                error = ext4_get_inode_loc(inode, &is->iloc);
1267
                if (error)
1268
                        goto cleanup;
1269
 
1270
                error = ext4_xattr_ibody_find(inode, &i, is);
1271
                if (error)
1272
                        goto cleanup;
1273
 
1274
                /* Remove the chosen entry from the inode */
1275
                error = ext4_xattr_ibody_set(handle, inode, &i, is);
1276
 
1277
                entry = IFIRST(header);
1278
                if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize)
1279
                        shift_bytes = new_extra_isize;
1280
                else
1281
                        shift_bytes = entry_size + size;
1282
                /* Adjust the offsets and shift the remaining entries ahead */
1283
                ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize -
1284
                        shift_bytes, (void *)raw_inode +
1285
                        EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes,
1286
                        (void *)header, total_ino - entry_size,
1287
                        inode->i_sb->s_blocksize);
1288
 
1289
                extra_isize += shift_bytes;
1290
                new_extra_isize -= shift_bytes;
1291
                EXT4_I(inode)->i_extra_isize = extra_isize;
1292
 
1293
                i.name = b_entry_name;
1294
                i.value = buffer;
1295
                i.value_len = size;
1296
                error = ext4_xattr_block_find(inode, &i, bs);
1297
                if (error)
1298
                        goto cleanup;
1299
 
1300
                /* Add entry which was removed from the inode into the block */
1301
                error = ext4_xattr_block_set(handle, inode, &i, bs);
1302
                if (error)
1303
                        goto cleanup;
1304
                kfree(b_entry_name);
1305
                kfree(buffer);
1306
                brelse(is->iloc.bh);
1307
                kfree(is);
1308
                kfree(bs);
1309
        }
1310
        brelse(bh);
1311
        up_write(&EXT4_I(inode)->xattr_sem);
1312
        return 0;
1313
 
1314
cleanup:
1315
        kfree(b_entry_name);
1316
        kfree(buffer);
1317
        if (is)
1318
                brelse(is->iloc.bh);
1319
        kfree(is);
1320
        kfree(bs);
1321
        brelse(bh);
1322
        up_write(&EXT4_I(inode)->xattr_sem);
1323
        return error;
1324
}
1325
 
1326
 
1327
 
1328
/*
1329
 * ext4_xattr_delete_inode()
1330
 *
1331
 * Free extended attribute resources associated with this inode. This
1332
 * is called immediately before an inode is freed. We have exclusive
1333
 * access to the inode.
1334
 */
1335
void
1336
ext4_xattr_delete_inode(handle_t *handle, struct inode *inode)
1337
{
1338
        struct buffer_head *bh = NULL;
1339
 
1340
        if (!EXT4_I(inode)->i_file_acl)
1341
                goto cleanup;
1342
        bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
1343
        if (!bh) {
1344
                ext4_error(inode->i_sb, __FUNCTION__,
1345
                        "inode %lu: block %llu read error", inode->i_ino,
1346
                        EXT4_I(inode)->i_file_acl);
1347
                goto cleanup;
1348
        }
1349
        if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
1350
            BHDR(bh)->h_blocks != cpu_to_le32(1)) {
1351
                ext4_error(inode->i_sb, __FUNCTION__,
1352
                        "inode %lu: bad block %llu", inode->i_ino,
1353
                        EXT4_I(inode)->i_file_acl);
1354
                goto cleanup;
1355
        }
1356
        ext4_xattr_release_block(handle, inode, bh);
1357
        EXT4_I(inode)->i_file_acl = 0;
1358
 
1359
cleanup:
1360
        brelse(bh);
1361
}
1362
 
1363
/*
1364
 * ext4_xattr_put_super()
1365
 *
1366
 * This is called when a file system is unmounted.
1367
 */
1368
void
1369
ext4_xattr_put_super(struct super_block *sb)
1370
{
1371
        mb_cache_shrink(sb->s_bdev);
1372
}
1373
 
1374
/*
1375
 * ext4_xattr_cache_insert()
1376
 *
1377
 * Create a new entry in the extended attribute cache, and insert
1378
 * it unless such an entry is already in the cache.
1379
 *
1380
 * Returns 0, or a negative error number on failure.
1381
 */
1382
static void
1383
ext4_xattr_cache_insert(struct buffer_head *bh)
1384
{
1385
        __u32 hash = le32_to_cpu(BHDR(bh)->h_hash);
1386
        struct mb_cache_entry *ce;
1387
        int error;
1388
 
1389
        ce = mb_cache_entry_alloc(ext4_xattr_cache);
1390
        if (!ce) {
1391
                ea_bdebug(bh, "out of memory");
1392
                return;
1393
        }
1394
        error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash);
1395
        if (error) {
1396
                mb_cache_entry_free(ce);
1397
                if (error == -EBUSY) {
1398
                        ea_bdebug(bh, "already in cache");
1399
                        error = 0;
1400
                }
1401
        } else {
1402
                ea_bdebug(bh, "inserting [%x]", (int)hash);
1403
                mb_cache_entry_release(ce);
1404
        }
1405
}
1406
 
1407
/*
1408
 * ext4_xattr_cmp()
1409
 *
1410
 * Compare two extended attribute blocks for equality.
1411
 *
1412
 * Returns 0 if the blocks are equal, 1 if they differ, and
1413
 * a negative error number on errors.
1414
 */
1415
static int
1416
ext4_xattr_cmp(struct ext4_xattr_header *header1,
1417
               struct ext4_xattr_header *header2)
1418
{
1419
        struct ext4_xattr_entry *entry1, *entry2;
1420
 
1421
        entry1 = ENTRY(header1+1);
1422
        entry2 = ENTRY(header2+1);
1423
        while (!IS_LAST_ENTRY(entry1)) {
1424
                if (IS_LAST_ENTRY(entry2))
1425
                        return 1;
1426
                if (entry1->e_hash != entry2->e_hash ||
1427
                    entry1->e_name_index != entry2->e_name_index ||
1428
                    entry1->e_name_len != entry2->e_name_len ||
1429
                    entry1->e_value_size != entry2->e_value_size ||
1430
                    memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len))
1431
                        return 1;
1432
                if (entry1->e_value_block != 0 || entry2->e_value_block != 0)
1433
                        return -EIO;
1434
                if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs),
1435
                           (char *)header2 + le16_to_cpu(entry2->e_value_offs),
1436
                           le32_to_cpu(entry1->e_value_size)))
1437
                        return 1;
1438
 
1439
                entry1 = EXT4_XATTR_NEXT(entry1);
1440
                entry2 = EXT4_XATTR_NEXT(entry2);
1441
        }
1442
        if (!IS_LAST_ENTRY(entry2))
1443
                return 1;
1444
        return 0;
1445
}
1446
 
1447
/*
1448
 * ext4_xattr_cache_find()
1449
 *
1450
 * Find an identical extended attribute block.
1451
 *
1452
 * Returns a pointer to the block found, or NULL if such a block was
1453
 * not found or an error occurred.
1454
 */
1455
static struct buffer_head *
1456
ext4_xattr_cache_find(struct inode *inode, struct ext4_xattr_header *header,
1457
                      struct mb_cache_entry **pce)
1458
{
1459
        __u32 hash = le32_to_cpu(header->h_hash);
1460
        struct mb_cache_entry *ce;
1461
 
1462
        if (!header->h_hash)
1463
                return NULL;  /* never share */
1464
        ea_idebug(inode, "looking for cached blocks [%x]", (int)hash);
1465
again:
1466
        ce = mb_cache_entry_find_first(ext4_xattr_cache, 0,
1467
                                       inode->i_sb->s_bdev, hash);
1468
        while (ce) {
1469
                struct buffer_head *bh;
1470
 
1471
                if (IS_ERR(ce)) {
1472
                        if (PTR_ERR(ce) == -EAGAIN)
1473
                                goto again;
1474
                        break;
1475
                }
1476
                bh = sb_bread(inode->i_sb, ce->e_block);
1477
                if (!bh) {
1478
                        ext4_error(inode->i_sb, __FUNCTION__,
1479
                                "inode %lu: block %lu read error",
1480
                                inode->i_ino, (unsigned long) ce->e_block);
1481
                } else if (le32_to_cpu(BHDR(bh)->h_refcount) >=
1482
                                EXT4_XATTR_REFCOUNT_MAX) {
1483
                        ea_idebug(inode, "block %lu refcount %d>=%d",
1484
                                  (unsigned long) ce->e_block,
1485
                                  le32_to_cpu(BHDR(bh)->h_refcount),
1486
                                          EXT4_XATTR_REFCOUNT_MAX);
1487
                } else if (ext4_xattr_cmp(header, BHDR(bh)) == 0) {
1488
                        *pce = ce;
1489
                        return bh;
1490
                }
1491
                brelse(bh);
1492
                ce = mb_cache_entry_find_next(ce, 0, inode->i_sb->s_bdev, hash);
1493
        }
1494
        return NULL;
1495
}
1496
 
1497
#define NAME_HASH_SHIFT 5
1498
#define VALUE_HASH_SHIFT 16
1499
 
1500
/*
1501
 * ext4_xattr_hash_entry()
1502
 *
1503
 * Compute the hash of an extended attribute.
1504
 */
1505
static inline void ext4_xattr_hash_entry(struct ext4_xattr_header *header,
1506
                                         struct ext4_xattr_entry *entry)
1507
{
1508
        __u32 hash = 0;
1509
        char *name = entry->e_name;
1510
        int n;
1511
 
1512
        for (n=0; n < entry->e_name_len; n++) {
1513
                hash = (hash << NAME_HASH_SHIFT) ^
1514
                       (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^
1515
                       *name++;
1516
        }
1517
 
1518
        if (entry->e_value_block == 0 && entry->e_value_size != 0) {
1519
                __le32 *value = (__le32 *)((char *)header +
1520
                        le16_to_cpu(entry->e_value_offs));
1521
                for (n = (le32_to_cpu(entry->e_value_size) +
1522
                     EXT4_XATTR_ROUND) >> EXT4_XATTR_PAD_BITS; n; n--) {
1523
                        hash = (hash << VALUE_HASH_SHIFT) ^
1524
                               (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^
1525
                               le32_to_cpu(*value++);
1526
                }
1527
        }
1528
        entry->e_hash = cpu_to_le32(hash);
1529
}
1530
 
1531
#undef NAME_HASH_SHIFT
1532
#undef VALUE_HASH_SHIFT
1533
 
1534
#define BLOCK_HASH_SHIFT 16
1535
 
1536
/*
1537
 * ext4_xattr_rehash()
1538
 *
1539
 * Re-compute the extended attribute hash value after an entry has changed.
1540
 */
1541
static void ext4_xattr_rehash(struct ext4_xattr_header *header,
1542
                              struct ext4_xattr_entry *entry)
1543
{
1544
        struct ext4_xattr_entry *here;
1545
        __u32 hash = 0;
1546
 
1547
        ext4_xattr_hash_entry(header, entry);
1548
        here = ENTRY(header+1);
1549
        while (!IS_LAST_ENTRY(here)) {
1550
                if (!here->e_hash) {
1551
                        /* Block is not shared if an entry's hash value == 0 */
1552
                        hash = 0;
1553
                        break;
1554
                }
1555
                hash = (hash << BLOCK_HASH_SHIFT) ^
1556
                       (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^
1557
                       le32_to_cpu(here->e_hash);
1558
                here = EXT4_XATTR_NEXT(here);
1559
        }
1560
        header->h_hash = cpu_to_le32(hash);
1561
}
1562
 
1563
#undef BLOCK_HASH_SHIFT
1564
 
1565
int __init
1566
init_ext4_xattr(void)
1567
{
1568
        ext4_xattr_cache = mb_cache_create("ext4_xattr", NULL,
1569
                sizeof(struct mb_cache_entry) +
1570
                sizeof(((struct mb_cache_entry *) 0)->e_indexes[0]), 1, 6);
1571
        if (!ext4_xattr_cache)
1572
                return -ENOMEM;
1573
        return 0;
1574
}
1575
 
1576
void
1577
exit_ext4_xattr(void)
1578
{
1579
        if (ext4_xattr_cache)
1580
                mb_cache_destroy(ext4_xattr_cache);
1581
        ext4_xattr_cache = NULL;
1582
}

powered by: WebSVN 2.1.0

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