add patch avoid-unnecesary-stalls-in-ext4_evict_inode
[ext4-patch-queue.git] / clean-up-ext4_xattr_inode_get
blob5fc5316baed14053a406ed2b12f48d931c479142
1 ext4: clean up ext4_xattr_inode_get()
3 From: Tahsin Erdogan <tahsin@google.com>
5 The input and output values of *size parameter are equal on successful
6 return from ext4_xattr_inode_get().  On error return, the callers ignore
7 the output value so there is no need to update it.
9 Also check for NULL return from ext4_bread().  If the actual xattr inode
10 size happens to be smaller than the expected size, ext4_bread() may
11 return NULL which would indicate data corruption.
13 Signed-off-by: Tahsin Erdogan <tahsin@google.com>
14 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
15 ---
16  fs/ext4/xattr.c | 35 +++++++++++++----------------------
17  1 file changed, 13 insertions(+), 22 deletions(-)
19 diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
20 index d9477d01be9b..8e855fc2eb03 100644
21 --- a/fs/ext4/xattr.c
22 +++ b/fs/ext4/xattr.c
23 @@ -278,37 +278,28 @@ ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
24  /*
25   * Read the EA value from an inode.
26   */
27 -static int
28 -ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t *size)
29 +static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size)
30  {
31         unsigned long block = 0;
32         struct buffer_head *bh = NULL;
33 -       int blocksize;
34 -       size_t csize, ret_size = 0;
36 -       if (*size == 0)
37 -               return 0;
38 +       int blocksize = ea_inode->i_sb->s_blocksize;
39 +       size_t csize, copied = 0;
41 -       blocksize = ea_inode->i_sb->s_blocksize;
43 -       while (ret_size < *size) {
44 -               csize = (*size - ret_size) > blocksize ? blocksize :
45 -                                                       *size - ret_size;
46 +       while (copied < size) {
47 +               csize = (size - copied) > blocksize ? blocksize : size - copied;
48                 bh = ext4_bread(NULL, ea_inode, block, 0);
49 -               if (IS_ERR(bh)) {
50 -                       *size = ret_size;
51 +               if (IS_ERR(bh))
52                         return PTR_ERR(bh);
53 -               }
54 +               if (!bh)
55 +                       return -EFSCORRUPTED;
57                 memcpy(buf, bh->b_data, csize);
58                 brelse(bh);
60                 buf += csize;
61                 block += 1;
62 -               ret_size += csize;
63 +               copied += csize;
64         }
66 -       *size = ret_size;
68         return 0;
69  }
71 @@ -360,7 +351,7 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
72   */
73  static int
74  ext4_xattr_inode_get(struct inode *inode, unsigned long ea_ino, void *buffer,
75 -                    size_t *size)
76 +                    size_t size)
77  {
78         struct inode *ea_inode;
79         int ret;
80 @@ -417,7 +408,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
81                 if (entry->e_value_inum) {
82                         error = ext4_xattr_inode_get(inode,
83                                              le32_to_cpu(entry->e_value_inum),
84 -                                            buffer, &size);
85 +                                            buffer, size);
86                         if (error)
87                                 goto cleanup;
88                 } else {
89 @@ -467,7 +458,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
90                 if (entry->e_value_inum) {
91                         error = ext4_xattr_inode_get(inode,
92                                              le32_to_cpu(entry->e_value_inum),
93 -                                            buffer, &size);
94 +                                            buffer, size);
95                         if (error)
96                                 goto cleanup;
97                 } else {
98 -- 
99 2.13.1.611.g7e3b11ae1-goog