LCOV - code coverage report
Current view: top level - fs/f2fs - xattr.c (source / functions) Hit Total Coverage
Test: Real Lines: 0 287 0.0 %
Date: 2020-10-17 15:46:16 Functions: 0 17 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * fs/f2fs/xattr.c
       4                 :            :  *
       5                 :            :  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
       6                 :            :  *             http://www.samsung.com/
       7                 :            :  *
       8                 :            :  * Portions of this code from linux/fs/ext2/xattr.c
       9                 :            :  *
      10                 :            :  * Copyright (C) 2001-2003 Andreas Gruenbacher <agruen@suse.de>
      11                 :            :  *
      12                 :            :  * Fix by Harrison Xing <harrison@mountainviewdata.com>.
      13                 :            :  * Extended attributes for symlinks and special files added per
      14                 :            :  *  suggestion of Luka Renko <luka.renko@hermes.si>.
      15                 :            :  * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
      16                 :            :  *  Red Hat Inc.
      17                 :            :  */
      18                 :            : #include <linux/rwsem.h>
      19                 :            : #include <linux/f2fs_fs.h>
      20                 :            : #include <linux/security.h>
      21                 :            : #include <linux/posix_acl_xattr.h>
      22                 :            : #include "f2fs.h"
      23                 :            : #include "xattr.h"
      24                 :            : #include "segment.h"
      25                 :            : 
      26                 :          0 : static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
      27                 :            :                 struct dentry *unused, struct inode *inode,
      28                 :            :                 const char *name, void *buffer, size_t size)
      29                 :            : {
      30                 :          0 :         struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
      31                 :            : 
      32                 :          0 :         switch (handler->flags) {
      33                 :            :         case F2FS_XATTR_INDEX_USER:
      34                 :          0 :                 if (!test_opt(sbi, XATTR_USER))
      35                 :            :                         return -EOPNOTSUPP;
      36                 :            :                 break;
      37                 :            :         case F2FS_XATTR_INDEX_TRUSTED:
      38                 :            :         case F2FS_XATTR_INDEX_SECURITY:
      39                 :            :                 break;
      40                 :            :         default:
      41                 :            :                 return -EINVAL;
      42                 :            :         }
      43                 :          0 :         return f2fs_getxattr(inode, handler->flags, name,
      44                 :            :                              buffer, size, NULL);
      45                 :            : }
      46                 :            : 
      47                 :          0 : static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
      48                 :            :                 struct dentry *unused, struct inode *inode,
      49                 :            :                 const char *name, const void *value,
      50                 :            :                 size_t size, int flags)
      51                 :            : {
      52                 :          0 :         struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
      53                 :            : 
      54                 :          0 :         switch (handler->flags) {
      55                 :            :         case F2FS_XATTR_INDEX_USER:
      56                 :          0 :                 if (!test_opt(sbi, XATTR_USER))
      57                 :            :                         return -EOPNOTSUPP;
      58                 :            :                 break;
      59                 :            :         case F2FS_XATTR_INDEX_TRUSTED:
      60                 :            :         case F2FS_XATTR_INDEX_SECURITY:
      61                 :            :                 break;
      62                 :            :         default:
      63                 :            :                 return -EINVAL;
      64                 :            :         }
      65                 :          0 :         return f2fs_setxattr(inode, handler->flags, name,
      66                 :            :                                         value, size, NULL, flags);
      67                 :            : }
      68                 :            : 
      69                 :          0 : static bool f2fs_xattr_user_list(struct dentry *dentry)
      70                 :            : {
      71                 :          0 :         struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
      72                 :            : 
      73                 :          0 :         return test_opt(sbi, XATTR_USER);
      74                 :            : }
      75                 :            : 
      76                 :          0 : static bool f2fs_xattr_trusted_list(struct dentry *dentry)
      77                 :            : {
      78                 :          0 :         return capable(CAP_SYS_ADMIN);
      79                 :            : }
      80                 :            : 
      81                 :          0 : static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
      82                 :            :                 struct dentry *unused, struct inode *inode,
      83                 :            :                 const char *name, void *buffer, size_t size)
      84                 :            : {
      85                 :          0 :         if (buffer)
      86                 :          0 :                 *((char *)buffer) = F2FS_I(inode)->i_advise;
      87                 :          0 :         return sizeof(char);
      88                 :            : }
      89                 :            : 
      90                 :          0 : static int f2fs_xattr_advise_set(const struct xattr_handler *handler,
      91                 :            :                 struct dentry *unused, struct inode *inode,
      92                 :            :                 const char *name, const void *value,
      93                 :            :                 size_t size, int flags)
      94                 :            : {
      95                 :          0 :         unsigned char old_advise = F2FS_I(inode)->i_advise;
      96                 :            :         unsigned char new_advise;
      97                 :            : 
      98                 :          0 :         if (!inode_owner_or_capable(inode))
      99                 :            :                 return -EPERM;
     100                 :          0 :         if (value == NULL)
     101                 :            :                 return -EINVAL;
     102                 :            : 
     103                 :          0 :         new_advise = *(char *)value;
     104                 :          0 :         if (new_advise & ~FADVISE_MODIFIABLE_BITS)
     105                 :            :                 return -EINVAL;
     106                 :            : 
     107                 :          0 :         new_advise = new_advise & FADVISE_MODIFIABLE_BITS;
     108                 :          0 :         new_advise |= old_advise & ~FADVISE_MODIFIABLE_BITS;
     109                 :            : 
     110                 :          0 :         F2FS_I(inode)->i_advise = new_advise;
     111                 :          0 :         f2fs_mark_inode_dirty_sync(inode, true);
     112                 :          0 :         return 0;
     113                 :            : }
     114                 :            : 
     115                 :            : #ifdef CONFIG_F2FS_FS_SECURITY
     116                 :            : static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
     117                 :            :                 void *page)
     118                 :            : {
     119                 :            :         const struct xattr *xattr;
     120                 :            :         int err = 0;
     121                 :            : 
     122                 :            :         for (xattr = xattr_array; xattr->name != NULL; xattr++) {
     123                 :            :                 err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY,
     124                 :            :                                 xattr->name, xattr->value,
     125                 :            :                                 xattr->value_len, (struct page *)page, 0);
     126                 :            :                 if (err < 0)
     127                 :            :                         break;
     128                 :            :         }
     129                 :            :         return err;
     130                 :            : }
     131                 :            : 
     132                 :            : int f2fs_init_security(struct inode *inode, struct inode *dir,
     133                 :            :                                 const struct qstr *qstr, struct page *ipage)
     134                 :            : {
     135                 :            :         return security_inode_init_security(inode, dir, qstr,
     136                 :            :                                 &f2fs_initxattrs, ipage);
     137                 :            : }
     138                 :            : #endif
     139                 :            : 
     140                 :            : const struct xattr_handler f2fs_xattr_user_handler = {
     141                 :            :         .prefix = XATTR_USER_PREFIX,
     142                 :            :         .flags  = F2FS_XATTR_INDEX_USER,
     143                 :            :         .list   = f2fs_xattr_user_list,
     144                 :            :         .get    = f2fs_xattr_generic_get,
     145                 :            :         .set    = f2fs_xattr_generic_set,
     146                 :            : };
     147                 :            : 
     148                 :            : const struct xattr_handler f2fs_xattr_trusted_handler = {
     149                 :            :         .prefix = XATTR_TRUSTED_PREFIX,
     150                 :            :         .flags  = F2FS_XATTR_INDEX_TRUSTED,
     151                 :            :         .list   = f2fs_xattr_trusted_list,
     152                 :            :         .get    = f2fs_xattr_generic_get,
     153                 :            :         .set    = f2fs_xattr_generic_set,
     154                 :            : };
     155                 :            : 
     156                 :            : const struct xattr_handler f2fs_xattr_advise_handler = {
     157                 :            :         .name   = F2FS_SYSTEM_ADVISE_NAME,
     158                 :            :         .flags  = F2FS_XATTR_INDEX_ADVISE,
     159                 :            :         .get    = f2fs_xattr_advise_get,
     160                 :            :         .set    = f2fs_xattr_advise_set,
     161                 :            : };
     162                 :            : 
     163                 :            : const struct xattr_handler f2fs_xattr_security_handler = {
     164                 :            :         .prefix = XATTR_SECURITY_PREFIX,
     165                 :            :         .flags  = F2FS_XATTR_INDEX_SECURITY,
     166                 :            :         .get    = f2fs_xattr_generic_get,
     167                 :            :         .set    = f2fs_xattr_generic_set,
     168                 :            : };
     169                 :            : 
     170                 :            : static const struct xattr_handler *f2fs_xattr_handler_map[] = {
     171                 :            :         [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
     172                 :            : #ifdef CONFIG_F2FS_FS_POSIX_ACL
     173                 :            :         [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
     174                 :            :         [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
     175                 :            : #endif
     176                 :            :         [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
     177                 :            : #ifdef CONFIG_F2FS_FS_SECURITY
     178                 :            :         [F2FS_XATTR_INDEX_SECURITY] = &f2fs_xattr_security_handler,
     179                 :            : #endif
     180                 :            :         [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler,
     181                 :            : };
     182                 :            : 
     183                 :            : const struct xattr_handler *f2fs_xattr_handlers[] = {
     184                 :            :         &f2fs_xattr_user_handler,
     185                 :            : #ifdef CONFIG_F2FS_FS_POSIX_ACL
     186                 :            :         &posix_acl_access_xattr_handler,
     187                 :            :         &posix_acl_default_xattr_handler,
     188                 :            : #endif
     189                 :            :         &f2fs_xattr_trusted_handler,
     190                 :            : #ifdef CONFIG_F2FS_FS_SECURITY
     191                 :            :         &f2fs_xattr_security_handler,
     192                 :            : #endif
     193                 :            :         &f2fs_xattr_advise_handler,
     194                 :            :         NULL,
     195                 :            : };
     196                 :            : 
     197                 :            : static inline const struct xattr_handler *f2fs_xattr_handler(int index)
     198                 :            : {
     199                 :            :         const struct xattr_handler *handler = NULL;
     200                 :            : 
     201                 :          0 :         if (index > 0 && index < ARRAY_SIZE(f2fs_xattr_handler_map))
     202                 :          0 :                 handler = f2fs_xattr_handler_map[index];
     203                 :            :         return handler;
     204                 :            : }
     205                 :            : 
     206                 :          0 : static struct f2fs_xattr_entry *__find_xattr(void *base_addr,
     207                 :            :                                 void *last_base_addr, int index,
     208                 :            :                                 size_t len, const char *name)
     209                 :            : {
     210                 :            :         struct f2fs_xattr_entry *entry;
     211                 :            : 
     212                 :          0 :         list_for_each_xattr(entry, base_addr) {
     213                 :          0 :                 if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
     214                 :          0 :                         (void *)XATTR_NEXT_ENTRY(entry) > last_base_addr)
     215                 :            :                         return NULL;
     216                 :            : 
     217                 :          0 :                 if (entry->e_name_index != index)
     218                 :          0 :                         continue;
     219                 :          0 :                 if (entry->e_name_len != len)
     220                 :          0 :                         continue;
     221                 :          0 :                 if (!memcmp(entry->e_name, name, len))
     222                 :            :                         break;
     223                 :            :         }
     224                 :          0 :         return entry;
     225                 :            : }
     226                 :            : 
     227                 :          0 : static struct f2fs_xattr_entry *__find_inline_xattr(struct inode *inode,
     228                 :            :                                 void *base_addr, void **last_addr, int index,
     229                 :            :                                 size_t len, const char *name)
     230                 :            : {
     231                 :            :         struct f2fs_xattr_entry *entry;
     232                 :          0 :         unsigned int inline_size = inline_xattr_size(inode);
     233                 :          0 :         void *max_addr = base_addr + inline_size;
     234                 :            : 
     235                 :          0 :         list_for_each_xattr(entry, base_addr) {
     236                 :          0 :                 if ((void *)entry + sizeof(__u32) > max_addr ||
     237                 :          0 :                         (void *)XATTR_NEXT_ENTRY(entry) > max_addr) {
     238                 :          0 :                         *last_addr = entry;
     239                 :          0 :                         return NULL;
     240                 :            :                 }
     241                 :          0 :                 if (entry->e_name_index != index)
     242                 :          0 :                         continue;
     243                 :          0 :                 if (entry->e_name_len != len)
     244                 :          0 :                         continue;
     245                 :          0 :                 if (!memcmp(entry->e_name, name, len))
     246                 :            :                         break;
     247                 :            :         }
     248                 :            : 
     249                 :            :         /* inline xattr header or entry across max inline xattr size */
     250                 :          0 :         if (IS_XATTR_LAST_ENTRY(entry) &&
     251                 :          0 :                 (void *)entry + sizeof(__u32) > max_addr) {
     252                 :          0 :                 *last_addr = entry;
     253                 :          0 :                 return NULL;
     254                 :            :         }
     255                 :          0 :         return entry;
     256                 :            : }
     257                 :            : 
     258                 :          0 : static int read_inline_xattr(struct inode *inode, struct page *ipage,
     259                 :            :                                                         void *txattr_addr)
     260                 :            : {
     261                 :            :         struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
     262                 :          0 :         unsigned int inline_size = inline_xattr_size(inode);
     263                 :            :         struct page *page = NULL;
     264                 :            :         void *inline_addr;
     265                 :            : 
     266                 :          0 :         if (ipage) {
     267                 :            :                 inline_addr = inline_xattr_addr(inode, ipage);
     268                 :            :         } else {
     269                 :          0 :                 page = f2fs_get_node_page(sbi, inode->i_ino);
     270                 :          0 :                 if (IS_ERR(page))
     271                 :          0 :                         return PTR_ERR(page);
     272                 :            : 
     273                 :            :                 inline_addr = inline_xattr_addr(inode, page);
     274                 :            :         }
     275                 :          0 :         memcpy(txattr_addr, inline_addr, inline_size);
     276                 :          0 :         f2fs_put_page(page, 1);
     277                 :            : 
     278                 :          0 :         return 0;
     279                 :            : }
     280                 :            : 
     281                 :          0 : static int read_xattr_block(struct inode *inode, void *txattr_addr)
     282                 :            : {
     283                 :            :         struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
     284                 :          0 :         nid_t xnid = F2FS_I(inode)->i_xattr_nid;
     285                 :          0 :         unsigned int inline_size = inline_xattr_size(inode);
     286                 :            :         struct page *xpage;
     287                 :            :         void *xattr_addr;
     288                 :            : 
     289                 :            :         /* The inode already has an extended attribute block. */
     290                 :          0 :         xpage = f2fs_get_node_page(sbi, xnid);
     291                 :          0 :         if (IS_ERR(xpage))
     292                 :          0 :                 return PTR_ERR(xpage);
     293                 :            : 
     294                 :            :         xattr_addr = page_address(xpage);
     295                 :          0 :         memcpy(txattr_addr + inline_size, xattr_addr, VALID_XATTR_BLOCK_SIZE);
     296                 :          0 :         f2fs_put_page(xpage, 1);
     297                 :            : 
     298                 :          0 :         return 0;
     299                 :            : }
     300                 :            : 
     301                 :          0 : static int lookup_all_xattrs(struct inode *inode, struct page *ipage,
     302                 :            :                                 unsigned int index, unsigned int len,
     303                 :            :                                 const char *name, struct f2fs_xattr_entry **xe,
     304                 :            :                                 void **base_addr, int *base_size)
     305                 :            : {
     306                 :            :         void *cur_addr, *txattr_addr, *last_txattr_addr;
     307                 :          0 :         void *last_addr = NULL;
     308                 :          0 :         nid_t xnid = F2FS_I(inode)->i_xattr_nid;
     309                 :          0 :         unsigned int inline_size = inline_xattr_size(inode);
     310                 :            :         int err = 0;
     311                 :            : 
     312                 :          0 :         if (!xnid && !inline_size)
     313                 :            :                 return -ENODATA;
     314                 :            : 
     315                 :          0 :         *base_size = XATTR_SIZE(xnid, inode) + XATTR_PADDING_SIZE;
     316                 :            :         txattr_addr = f2fs_kzalloc(F2FS_I_SB(inode), *base_size, GFP_NOFS);
     317                 :          0 :         if (!txattr_addr)
     318                 :            :                 return -ENOMEM;
     319                 :            : 
     320                 :          0 :         last_txattr_addr = (void *)txattr_addr + XATTR_SIZE(xnid, inode);
     321                 :            : 
     322                 :            :         /* read from inline xattr */
     323                 :          0 :         if (inline_size) {
     324                 :          0 :                 err = read_inline_xattr(inode, ipage, txattr_addr);
     325                 :          0 :                 if (err)
     326                 :            :                         goto out;
     327                 :            : 
     328                 :          0 :                 *xe = __find_inline_xattr(inode, txattr_addr, &last_addr,
     329                 :            :                                                 index, len, name);
     330                 :          0 :                 if (*xe) {
     331                 :          0 :                         *base_size = inline_size;
     332                 :          0 :                         goto check;
     333                 :            :                 }
     334                 :            :         }
     335                 :            : 
     336                 :            :         /* read from xattr node block */
     337                 :          0 :         if (xnid) {
     338                 :          0 :                 err = read_xattr_block(inode, txattr_addr);
     339                 :          0 :                 if (err)
     340                 :            :                         goto out;
     341                 :            :         }
     342                 :            : 
     343                 :          0 :         if (last_addr)
     344                 :          0 :                 cur_addr = XATTR_HDR(last_addr) - 1;
     345                 :            :         else
     346                 :            :                 cur_addr = txattr_addr;
     347                 :            : 
     348                 :          0 :         *xe = __find_xattr(cur_addr, last_txattr_addr, index, len, name);
     349                 :          0 :         if (!*xe) {
     350                 :          0 :                 f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
     351                 :            :                                                                 inode->i_ino);
     352                 :            :                 set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
     353                 :            :                 err = -EFSCORRUPTED;
     354                 :          0 :                 goto out;
     355                 :            :         }
     356                 :            : check:
     357                 :          0 :         if (IS_XATTR_LAST_ENTRY(*xe)) {
     358                 :            :                 err = -ENODATA;
     359                 :            :                 goto out;
     360                 :            :         }
     361                 :            : 
     362                 :          0 :         *base_addr = txattr_addr;
     363                 :          0 :         return 0;
     364                 :            : out:
     365                 :          0 :         kvfree(txattr_addr);
     366                 :          0 :         return err;
     367                 :            : }
     368                 :            : 
     369                 :          0 : static int read_all_xattrs(struct inode *inode, struct page *ipage,
     370                 :            :                                                         void **base_addr)
     371                 :            : {
     372                 :            :         struct f2fs_xattr_header *header;
     373                 :          0 :         nid_t xnid = F2FS_I(inode)->i_xattr_nid;
     374                 :            :         unsigned int size = VALID_XATTR_BLOCK_SIZE;
     375                 :          0 :         unsigned int inline_size = inline_xattr_size(inode);
     376                 :            :         void *txattr_addr;
     377                 :            :         int err;
     378                 :            : 
     379                 :          0 :         txattr_addr = f2fs_kzalloc(F2FS_I_SB(inode),
     380                 :            :                         inline_size + size + XATTR_PADDING_SIZE, GFP_NOFS);
     381                 :          0 :         if (!txattr_addr)
     382                 :            :                 return -ENOMEM;
     383                 :            : 
     384                 :            :         /* read from inline xattr */
     385                 :          0 :         if (inline_size) {
     386                 :          0 :                 err = read_inline_xattr(inode, ipage, txattr_addr);
     387                 :          0 :                 if (err)
     388                 :            :                         goto fail;
     389                 :            :         }
     390                 :            : 
     391                 :            :         /* read from xattr node block */
     392                 :          0 :         if (xnid) {
     393                 :          0 :                 err = read_xattr_block(inode, txattr_addr);
     394                 :          0 :                 if (err)
     395                 :            :                         goto fail;
     396                 :            :         }
     397                 :            : 
     398                 :            :         header = XATTR_HDR(txattr_addr);
     399                 :            : 
     400                 :            :         /* never been allocated xattrs */
     401                 :          0 :         if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) {
     402                 :          0 :                 header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC);
     403                 :          0 :                 header->h_refcount = cpu_to_le32(1);
     404                 :            :         }
     405                 :          0 :         *base_addr = txattr_addr;
     406                 :          0 :         return 0;
     407                 :            : fail:
     408                 :          0 :         kvfree(txattr_addr);
     409                 :          0 :         return err;
     410                 :            : }
     411                 :            : 
     412                 :          0 : static inline int write_all_xattrs(struct inode *inode, __u32 hsize,
     413                 :            :                                 void *txattr_addr, struct page *ipage)
     414                 :            : {
     415                 :            :         struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
     416                 :          0 :         size_t inline_size = inline_xattr_size(inode);
     417                 :            :         struct page *in_page = NULL;
     418                 :            :         void *xattr_addr;
     419                 :            :         void *inline_addr = NULL;
     420                 :            :         struct page *xpage;
     421                 :          0 :         nid_t new_nid = 0;
     422                 :            :         int err = 0;
     423                 :            : 
     424                 :          0 :         if (hsize > inline_size && !F2FS_I(inode)->i_xattr_nid)
     425                 :          0 :                 if (!f2fs_alloc_nid(sbi, &new_nid))
     426                 :            :                         return -ENOSPC;
     427                 :            : 
     428                 :            :         /* write to inline xattr */
     429                 :          0 :         if (inline_size) {
     430                 :          0 :                 if (ipage) {
     431                 :            :                         inline_addr = inline_xattr_addr(inode, ipage);
     432                 :            :                 } else {
     433                 :          0 :                         in_page = f2fs_get_node_page(sbi, inode->i_ino);
     434                 :          0 :                         if (IS_ERR(in_page)) {
     435                 :          0 :                                 f2fs_alloc_nid_failed(sbi, new_nid);
     436                 :          0 :                                 return PTR_ERR(in_page);
     437                 :            :                         }
     438                 :            :                         inline_addr = inline_xattr_addr(inode, in_page);
     439                 :            :                 }
     440                 :            : 
     441                 :          0 :                 f2fs_wait_on_page_writeback(ipage ? ipage : in_page,
     442                 :            :                                                         NODE, true, true);
     443                 :            :                 /* no need to use xattr node block */
     444                 :          0 :                 if (hsize <= inline_size) {
     445                 :          0 :                         err = f2fs_truncate_xattr_node(inode);
     446                 :          0 :                         f2fs_alloc_nid_failed(sbi, new_nid);
     447                 :          0 :                         if (err) {
     448                 :          0 :                                 f2fs_put_page(in_page, 1);
     449                 :          0 :                                 return err;
     450                 :            :                         }
     451                 :          0 :                         memcpy(inline_addr, txattr_addr, inline_size);
     452                 :          0 :                         set_page_dirty(ipage ? ipage : in_page);
     453                 :          0 :                         goto in_page_out;
     454                 :            :                 }
     455                 :            :         }
     456                 :            : 
     457                 :            :         /* write to xattr node block */
     458                 :          0 :         if (F2FS_I(inode)->i_xattr_nid) {
     459                 :          0 :                 xpage = f2fs_get_node_page(sbi, F2FS_I(inode)->i_xattr_nid);
     460                 :          0 :                 if (IS_ERR(xpage)) {
     461                 :            :                         err = PTR_ERR(xpage);
     462                 :          0 :                         f2fs_alloc_nid_failed(sbi, new_nid);
     463                 :          0 :                         goto in_page_out;
     464                 :            :                 }
     465                 :          0 :                 f2fs_bug_on(sbi, new_nid);
     466                 :          0 :                 f2fs_wait_on_page_writeback(xpage, NODE, true, true);
     467                 :            :         } else {
     468                 :            :                 struct dnode_of_data dn;
     469                 :          0 :                 set_new_dnode(&dn, inode, NULL, NULL, new_nid);
     470                 :          0 :                 xpage = f2fs_new_node_page(&dn, XATTR_NODE_OFFSET);
     471                 :          0 :                 if (IS_ERR(xpage)) {
     472                 :            :                         err = PTR_ERR(xpage);
     473                 :          0 :                         f2fs_alloc_nid_failed(sbi, new_nid);
     474                 :          0 :                         goto in_page_out;
     475                 :            :                 }
     476                 :          0 :                 f2fs_alloc_nid_done(sbi, new_nid);
     477                 :            :         }
     478                 :            :         xattr_addr = page_address(xpage);
     479                 :            : 
     480                 :          0 :         if (inline_size)
     481                 :          0 :                 memcpy(inline_addr, txattr_addr, inline_size);
     482                 :          0 :         memcpy(xattr_addr, txattr_addr + inline_size, VALID_XATTR_BLOCK_SIZE);
     483                 :            : 
     484                 :          0 :         if (inline_size)
     485                 :          0 :                 set_page_dirty(ipage ? ipage : in_page);
     486                 :          0 :         set_page_dirty(xpage);
     487                 :            : 
     488                 :          0 :         f2fs_put_page(xpage, 1);
     489                 :            : in_page_out:
     490                 :          0 :         f2fs_put_page(in_page, 1);
     491                 :          0 :         return err;
     492                 :            : }
     493                 :            : 
     494                 :          0 : int f2fs_getxattr(struct inode *inode, int index, const char *name,
     495                 :            :                 void *buffer, size_t buffer_size, struct page *ipage)
     496                 :            : {
     497                 :          0 :         struct f2fs_xattr_entry *entry = NULL;
     498                 :            :         int error = 0;
     499                 :            :         unsigned int size, len;
     500                 :          0 :         void *base_addr = NULL;
     501                 :            :         int base_size;
     502                 :            : 
     503                 :          0 :         if (name == NULL)
     504                 :            :                 return -EINVAL;
     505                 :            : 
     506                 :          0 :         len = strlen(name);
     507                 :          0 :         if (len > F2FS_NAME_LEN)
     508                 :            :                 return -ERANGE;
     509                 :            : 
     510                 :          0 :         down_read(&F2FS_I(inode)->i_xattr_sem);
     511                 :          0 :         error = lookup_all_xattrs(inode, ipage, index, len, name,
     512                 :            :                                 &entry, &base_addr, &base_size);
     513                 :          0 :         up_read(&F2FS_I(inode)->i_xattr_sem);
     514                 :          0 :         if (error)
     515                 :            :                 return error;
     516                 :            : 
     517                 :          0 :         size = le16_to_cpu(entry->e_value_size);
     518                 :            : 
     519                 :          0 :         if (buffer && size > buffer_size) {
     520                 :            :                 error = -ERANGE;
     521                 :            :                 goto out;
     522                 :            :         }
     523                 :            : 
     524                 :          0 :         if (buffer) {
     525                 :          0 :                 char *pval = entry->e_name + entry->e_name_len;
     526                 :            : 
     527                 :          0 :                 if (base_size - (pval - (char *)base_addr) < size) {
     528                 :            :                         error = -ERANGE;
     529                 :            :                         goto out;
     530                 :            :                 }
     531                 :          0 :                 memcpy(buffer, pval, size);
     532                 :            :         }
     533                 :          0 :         error = size;
     534                 :            : out:
     535                 :          0 :         kvfree(base_addr);
     536                 :          0 :         return error;
     537                 :            : }
     538                 :            : 
     539                 :          0 : ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
     540                 :            : {
     541                 :            :         struct inode *inode = d_inode(dentry);
     542                 :          0 :         nid_t xnid = F2FS_I(inode)->i_xattr_nid;
     543                 :            :         struct f2fs_xattr_entry *entry;
     544                 :            :         void *base_addr, *last_base_addr;
     545                 :            :         int error = 0;
     546                 :            :         size_t rest = buffer_size;
     547                 :            : 
     548                 :          0 :         down_read(&F2FS_I(inode)->i_xattr_sem);
     549                 :          0 :         error = read_all_xattrs(inode, NULL, &base_addr);
     550                 :          0 :         up_read(&F2FS_I(inode)->i_xattr_sem);
     551                 :          0 :         if (error)
     552                 :            :                 return error;
     553                 :            : 
     554                 :          0 :         last_base_addr = (void *)base_addr + XATTR_SIZE(xnid, inode);
     555                 :            : 
     556                 :          0 :         list_for_each_xattr(entry, base_addr) {
     557                 :            :                 const struct xattr_handler *handler =
     558                 :          0 :                         f2fs_xattr_handler(entry->e_name_index);
     559                 :            :                 const char *prefix;
     560                 :            :                 size_t prefix_len;
     561                 :            :                 size_t size;
     562                 :            : 
     563                 :          0 :                 if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
     564                 :          0 :                         (void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) {
     565                 :          0 :                         f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
     566                 :            :                                                 inode->i_ino);
     567                 :            :                         set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
     568                 :            :                         error = -EFSCORRUPTED;
     569                 :          0 :                         goto cleanup;
     570                 :            :                 }
     571                 :            : 
     572                 :          0 :                 if (!handler || (handler->list && !handler->list(dentry)))
     573                 :          0 :                         continue;
     574                 :            : 
     575                 :            :                 prefix = xattr_prefix(handler);
     576                 :          0 :                 prefix_len = strlen(prefix);
     577                 :          0 :                 size = prefix_len + entry->e_name_len + 1;
     578                 :          0 :                 if (buffer) {
     579                 :          0 :                         if (size > rest) {
     580                 :            :                                 error = -ERANGE;
     581                 :            :                                 goto cleanup;
     582                 :            :                         }
     583                 :          0 :                         memcpy(buffer, prefix, prefix_len);
     584                 :          0 :                         buffer += prefix_len;
     585                 :          0 :                         memcpy(buffer, entry->e_name, entry->e_name_len);
     586                 :          0 :                         buffer += entry->e_name_len;
     587                 :          0 :                         *buffer++ = 0;
     588                 :            :                 }
     589                 :          0 :                 rest -= size;
     590                 :            :         }
     591                 :          0 :         error = buffer_size - rest;
     592                 :            : cleanup:
     593                 :          0 :         kvfree(base_addr);
     594                 :          0 :         return error;
     595                 :            : }
     596                 :            : 
     597                 :            : static bool f2fs_xattr_value_same(struct f2fs_xattr_entry *entry,
     598                 :            :                                         const void *value, size_t size)
     599                 :            : {
     600                 :          0 :         void *pval = entry->e_name + entry->e_name_len;
     601                 :            : 
     602                 :          0 :         return (le16_to_cpu(entry->e_value_size) == size) &&
     603                 :          0 :                                         !memcmp(pval, value, size);
     604                 :            : }
     605                 :            : 
     606                 :          0 : static int __f2fs_setxattr(struct inode *inode, int index,
     607                 :            :                         const char *name, const void *value, size_t size,
     608                 :            :                         struct page *ipage, int flags)
     609                 :            : {
     610                 :            :         struct f2fs_xattr_entry *here, *last;
     611                 :            :         void *base_addr, *last_base_addr;
     612                 :          0 :         nid_t xnid = F2FS_I(inode)->i_xattr_nid;
     613                 :            :         int found, newsize;
     614                 :            :         size_t len;
     615                 :            :         __u32 new_hsize;
     616                 :            :         int error = 0;
     617                 :            : 
     618                 :          0 :         if (name == NULL)
     619                 :            :                 return -EINVAL;
     620                 :            : 
     621                 :          0 :         if (value == NULL)
     622                 :            :                 size = 0;
     623                 :            : 
     624                 :          0 :         len = strlen(name);
     625                 :            : 
     626                 :          0 :         if (len > F2FS_NAME_LEN)
     627                 :            :                 return -ERANGE;
     628                 :            : 
     629                 :          0 :         if (size > MAX_VALUE_LEN(inode))
     630                 :            :                 return -E2BIG;
     631                 :            : 
     632                 :          0 :         error = read_all_xattrs(inode, ipage, &base_addr);
     633                 :          0 :         if (error)
     634                 :            :                 return error;
     635                 :            : 
     636                 :          0 :         last_base_addr = (void *)base_addr + XATTR_SIZE(xnid, inode);
     637                 :            : 
     638                 :            :         /* find entry with wanted name. */
     639                 :          0 :         here = __find_xattr(base_addr, last_base_addr, index, len, name);
     640                 :          0 :         if (!here) {
     641                 :          0 :                 f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
     642                 :            :                                                                 inode->i_ino);
     643                 :            :                 set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
     644                 :            :                 error = -EFSCORRUPTED;
     645                 :          0 :                 goto exit;
     646                 :            :         }
     647                 :            : 
     648                 :          0 :         found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1;
     649                 :            : 
     650                 :          0 :         if (found) {
     651                 :          0 :                 if ((flags & XATTR_CREATE)) {
     652                 :            :                         error = -EEXIST;
     653                 :            :                         goto exit;
     654                 :            :                 }
     655                 :            : 
     656                 :          0 :                 if (value && f2fs_xattr_value_same(here, value, size))
     657                 :            :                         goto exit;
     658                 :          0 :         } else if ((flags & XATTR_REPLACE)) {
     659                 :            :                 error = -ENODATA;
     660                 :            :                 goto exit;
     661                 :            :         }
     662                 :            : 
     663                 :            :         last = here;
     664                 :          0 :         while (!IS_XATTR_LAST_ENTRY(last))
     665                 :          0 :                 last = XATTR_NEXT_ENTRY(last);
     666                 :            : 
     667                 :          0 :         newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + len + size);
     668                 :            : 
     669                 :            :         /* 1. Check space */
     670                 :          0 :         if (value) {
     671                 :            :                 int free;
     672                 :            :                 /*
     673                 :            :                  * If value is NULL, it is remove operation.
     674                 :            :                  * In case of update operation, we calculate free.
     675                 :            :                  */
     676                 :          0 :                 free = MIN_OFFSET(inode) - ((char *)last - (char *)base_addr);
     677                 :          0 :                 if (found)
     678                 :          0 :                         free = free + ENTRY_SIZE(here);
     679                 :            : 
     680                 :          0 :                 if (unlikely(free < newsize)) {
     681                 :            :                         error = -E2BIG;
     682                 :            :                         goto exit;
     683                 :            :                 }
     684                 :            :         }
     685                 :            : 
     686                 :            :         /* 2. Remove old entry */
     687                 :          0 :         if (found) {
     688                 :            :                 /*
     689                 :            :                  * If entry is found, remove old entry.
     690                 :            :                  * If not found, remove operation is not needed.
     691                 :            :                  */
     692                 :          0 :                 struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here);
     693                 :          0 :                 int oldsize = ENTRY_SIZE(here);
     694                 :            : 
     695                 :          0 :                 memmove(here, next, (char *)last - (char *)next);
     696                 :          0 :                 last = (struct f2fs_xattr_entry *)((char *)last - oldsize);
     697                 :          0 :                 memset(last, 0, oldsize);
     698                 :            :         }
     699                 :            : 
     700                 :          0 :         new_hsize = (char *)last - (char *)base_addr;
     701                 :            : 
     702                 :            :         /* 3. Write new entry */
     703                 :          0 :         if (value) {
     704                 :            :                 char *pval;
     705                 :            :                 /*
     706                 :            :                  * Before we come here, old entry is removed.
     707                 :            :                  * We just write new entry.
     708                 :            :                  */
     709                 :          0 :                 last->e_name_index = index;
     710                 :          0 :                 last->e_name_len = len;
     711                 :          0 :                 memcpy(last->e_name, name, len);
     712                 :          0 :                 pval = last->e_name + len;
     713                 :          0 :                 memcpy(pval, value, size);
     714                 :          0 :                 last->e_value_size = cpu_to_le16(size);
     715                 :          0 :                 new_hsize += newsize;
     716                 :            :         }
     717                 :            : 
     718                 :          0 :         error = write_all_xattrs(inode, new_hsize, base_addr, ipage);
     719                 :          0 :         if (error)
     720                 :            :                 goto exit;
     721                 :            : 
     722                 :          0 :         if (is_inode_flag_set(inode, FI_ACL_MODE)) {
     723                 :          0 :                 inode->i_mode = F2FS_I(inode)->i_acl_mode;
     724                 :          0 :                 inode->i_ctime = current_time(inode);
     725                 :          0 :                 clear_inode_flag(inode, FI_ACL_MODE);
     726                 :            :         }
     727                 :          0 :         if (index == F2FS_XATTR_INDEX_ENCRYPTION &&
     728                 :          0 :                         !strcmp(name, F2FS_XATTR_NAME_ENCRYPTION_CONTEXT))
     729                 :          0 :                 f2fs_set_encrypted_inode(inode);
     730                 :          0 :         f2fs_mark_inode_dirty_sync(inode, true);
     731                 :          0 :         if (!error && S_ISDIR(inode->i_mode))
     732                 :            :                 set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);
     733                 :            : exit:
     734                 :          0 :         kvfree(base_addr);
     735                 :          0 :         return error;
     736                 :            : }
     737                 :            : 
     738                 :          0 : int f2fs_setxattr(struct inode *inode, int index, const char *name,
     739                 :            :                                 const void *value, size_t size,
     740                 :            :                                 struct page *ipage, int flags)
     741                 :            : {
     742                 :            :         struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
     743                 :            :         int err;
     744                 :            : 
     745                 :          0 :         if (unlikely(f2fs_cp_error(sbi)))
     746                 :            :                 return -EIO;
     747                 :          0 :         if (!f2fs_is_checkpoint_ready(sbi))
     748                 :            :                 return -ENOSPC;
     749                 :            : 
     750                 :          0 :         err = dquot_initialize(inode);
     751                 :          0 :         if (err)
     752                 :            :                 return err;
     753                 :            : 
     754                 :            :         /* this case is only from f2fs_init_inode_metadata */
     755                 :          0 :         if (ipage)
     756                 :          0 :                 return __f2fs_setxattr(inode, index, name, value,
     757                 :            :                                                 size, ipage, flags);
     758                 :          0 :         f2fs_balance_fs(sbi, true);
     759                 :            : 
     760                 :            :         f2fs_lock_op(sbi);
     761                 :            :         /* protect xattr_ver */
     762                 :          0 :         down_write(&F2FS_I(inode)->i_sem);
     763                 :          0 :         down_write(&F2FS_I(inode)->i_xattr_sem);
     764                 :          0 :         err = __f2fs_setxattr(inode, index, name, value, size, ipage, flags);
     765                 :          0 :         up_write(&F2FS_I(inode)->i_xattr_sem);
     766                 :          0 :         up_write(&F2FS_I(inode)->i_sem);
     767                 :            :         f2fs_unlock_op(sbi);
     768                 :            : 
     769                 :            :         f2fs_update_time(sbi, REQ_TIME);
     770                 :          0 :         return err;
     771                 :            : }
    

Generated by: LCOV version 1.14