]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 14 Nov 2015 02:02:30 +0000 (18:02 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 14 Nov 2015 02:02:30 +0000 (18:02 -0800)
Pull vfs xattr cleanups from Al Viro.

* 'for-linus-3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  f2fs: xattr simplifications
  squashfs: xattr simplifications
  9p: xattr simplifications
  xattr handlers: Pass handler to operations instead of flags
  jffs2: Add missing capability check for listing trusted xattrs
  hfsplus: Remove unused xattr handler list operations
  ubifs: Remove unused security xattr handler
  vfs: Fix the posix_acl_xattr_list return value
  vfs: Check attribute names in posix acl xattr handers

1  2 
fs/nfs/nfs4proc.c
fs/ubifs/super.c
fs/ubifs/ubifs.h
fs/ubifs/xattr.c
fs/xfs/xfs_xattr.c

diff --combined fs/nfs/nfs4proc.c
index ff5bddc49a2a30449a63a6c2a32a2aadc6db84b5,ab84c4d151480e1824c68f0dfae8df39ae8875cb..765a035593638cfd17b4aedd646c0362068343c6
@@@ -78,6 -78,7 +78,6 @@@ struct nfs4_opendata
  static int _nfs4_proc_open(struct nfs4_opendata *data);
  static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
  static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
 -static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *, struct nfs4_state *, long *);
  static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
  static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label);
  static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label);
@@@ -238,7 -239,6 +238,7 @@@ const u32 nfs4_fsinfo_bitmap[3] = { FAT
                        FATTR4_WORD1_TIME_DELTA
                        | FATTR4_WORD1_FS_LAYOUT_TYPES,
                        FATTR4_WORD2_LAYOUT_BLKSIZE
 +                      | FATTR4_WORD2_CLONE_BLKSIZE
  };
  
  const u32 nfs4_fs_locations_bitmap[3] = {
@@@ -344,16 -344,13 +344,16 @@@ static int nfs4_delay(struct rpc_clnt *
  /* This is the error handling routine for processes that are allowed
   * to sleep.
   */
 -int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
 +static int nfs4_do_handle_exception(struct nfs_server *server,
 +              int errorcode, struct nfs4_exception *exception)
  {
        struct nfs_client *clp = server->nfs_client;
        struct nfs4_state *state = exception->state;
        struct inode *inode = exception->inode;
        int ret = errorcode;
  
 +      exception->delay = 0;
 +      exception->recovering = 0;
        exception->retry = 0;
        switch(errorcode) {
                case 0:
                case -NFS4ERR_DELEG_REVOKED:
                case -NFS4ERR_ADMIN_REVOKED:
                case -NFS4ERR_BAD_STATEID:
 -                      if (inode && nfs4_have_delegation(inode, FMODE_READ)) {
 -                              nfs4_inode_return_delegation(inode);
 -                              exception->retry = 1;
 -                              return 0;
 -                      }
 +                      if (inode && nfs_async_inode_return_delegation(inode,
 +                                              NULL) == 0)
 +                              goto wait_on_recovery;
                        if (state == NULL)
                                break;
                        ret = nfs4_schedule_stateid_recovery(server, state);
                                ret = -EBUSY;
                                break;
                        }
 -              case -NFS4ERR_GRACE:
                case -NFS4ERR_DELAY:
 -                      ret = nfs4_delay(server->client, &exception->timeout);
 -                      if (ret != 0)
 -                              break;
 +                      nfs_inc_server_stats(server, NFSIOS_DELAY);
 +              case -NFS4ERR_GRACE:
 +                      exception->delay = 1;
 +                      return 0;
 +
                case -NFS4ERR_RETRY_UNCACHED_REP:
                case -NFS4ERR_OLD_STATEID:
                        exception->retry = 1;
        /* We failed to handle the error */
        return nfs4_map_errors(ret);
  wait_on_recovery:
 -      ret = nfs4_wait_clnt_recover(clp);
 +      exception->recovering = 1;
 +      return 0;
 +}
 +
 +/* This is the error handling routine for processes that are allowed
 + * to sleep.
 + */
 +int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
 +{
 +      struct nfs_client *clp = server->nfs_client;
 +      int ret;
 +
 +      ret = nfs4_do_handle_exception(server, errorcode, exception);
 +      if (exception->delay) {
 +              ret = nfs4_delay(server->client, &exception->timeout);
 +              goto out_retry;
 +      }
 +      if (exception->recovering) {
 +              ret = nfs4_wait_clnt_recover(clp);
 +              if (test_bit(NFS_MIG_FAILED, &server->mig_status))
 +                      return -EIO;
 +              goto out_retry;
 +      }
 +      return ret;
 +out_retry:
 +      if (ret == 0)
 +              exception->retry = 1;
 +      return ret;
 +}
 +
 +static int
 +nfs4_async_handle_exception(struct rpc_task *task, struct nfs_server *server,
 +              int errorcode, struct nfs4_exception *exception)
 +{
 +      struct nfs_client *clp = server->nfs_client;
 +      int ret;
 +
 +      ret = nfs4_do_handle_exception(server, errorcode, exception);
 +      if (exception->delay) {
 +              rpc_delay(task, nfs4_update_delay(&exception->timeout));
 +              goto out_retry;
 +      }
 +      if (exception->recovering) {
 +              rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
 +              if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
 +                      rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
 +              goto out_retry;
 +      }
        if (test_bit(NFS_MIG_FAILED, &server->mig_status))
 -              return -EIO;
 +              ret = -EIO;
 +      return ret;
 +out_retry:
        if (ret == 0)
                exception->retry = 1;
        return ret;
  }
  
 +static int
 +nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server,
 +                      struct nfs4_state *state, long *timeout)
 +{
 +      struct nfs4_exception exception = {
 +              .state = state,
 +      };
 +
 +      if (task->tk_status >= 0)
 +              return 0;
 +      if (timeout)
 +              exception.timeout = *timeout;
 +      task->tk_status = nfs4_async_handle_exception(task, server,
 +                      task->tk_status,
 +                      &exception);
 +      if (exception.delay && timeout)
 +              *timeout = exception.timeout;
 +      if (exception.retry)
 +              return -EAGAIN;
 +      return 0;
 +}
 +
  /*
   * Return 'true' if 'clp' is using an rpc_client that is integrity protected
   * or 'false' otherwise.
@@@ -4603,7 -4530,7 +4603,7 @@@ static inline int nfs4_server_supports_
  #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE)
  
  static int buf_to_pages_noslab(const void *buf, size_t buflen,
 -              struct page **pages, unsigned int *pgbase)
 +              struct page **pages)
  {
        struct page *newpage, **spages;
        int rc = 0;
@@@ -4747,6 -4674,7 +4747,6 @@@ static ssize_t __nfs4_get_acl_uncached(
                goto out_free;
  
        args.acl_len = npages * PAGE_SIZE;
 -      args.acl_pgbase = 0;
  
        dprintk("%s  buf %p buflen %zu npages %d args.acl_len %zu\n",
                __func__, buf, buflen, npages, args.acl_len);
@@@ -4838,7 -4766,7 +4838,7 @@@ static int __nfs4_proc_set_acl(struct i
                return -EOPNOTSUPP;
        if (npages > ARRAY_SIZE(pages))
                return -ERANGE;
 -      i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
 +      i = buf_to_pages_noslab(buf, buflen, arg.acl_pages);
        if (i < 0)
                return i;
        nfs4_inode_return_delegation(inode);
@@@ -5027,6 -4955,79 +5027,6 @@@ out
  #endif        /* CONFIG_NFS_V4_SECURITY_LABEL */
  
  
 -static int
 -nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
 -                      struct nfs4_state *state, long *timeout)
 -{
 -      struct nfs_client *clp = server->nfs_client;
 -
 -      if (task->tk_status >= 0)
 -              return 0;
 -      switch(task->tk_status) {
 -              case -NFS4ERR_DELEG_REVOKED:
 -              case -NFS4ERR_ADMIN_REVOKED:
 -              case -NFS4ERR_BAD_STATEID:
 -              case -NFS4ERR_OPENMODE:
 -                      if (state == NULL)
 -                              break;
 -                      if (nfs4_schedule_stateid_recovery(server, state) < 0)
 -                              goto recovery_failed;
 -                      goto wait_on_recovery;
 -              case -NFS4ERR_EXPIRED:
 -                      if (state != NULL) {
 -                              if (nfs4_schedule_stateid_recovery(server, state) < 0)
 -                                      goto recovery_failed;
 -                      }
 -              case -NFS4ERR_STALE_STATEID:
 -              case -NFS4ERR_STALE_CLIENTID:
 -                      nfs4_schedule_lease_recovery(clp);
 -                      goto wait_on_recovery;
 -              case -NFS4ERR_MOVED:
 -                      if (nfs4_schedule_migration_recovery(server) < 0)
 -                              goto recovery_failed;
 -                      goto wait_on_recovery;
 -              case -NFS4ERR_LEASE_MOVED:
 -                      nfs4_schedule_lease_moved_recovery(clp);
 -                      goto wait_on_recovery;
 -#if defined(CONFIG_NFS_V4_1)
 -              case -NFS4ERR_BADSESSION:
 -              case -NFS4ERR_BADSLOT:
 -              case -NFS4ERR_BAD_HIGH_SLOT:
 -              case -NFS4ERR_DEADSESSION:
 -              case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
 -              case -NFS4ERR_SEQ_FALSE_RETRY:
 -              case -NFS4ERR_SEQ_MISORDERED:
 -                      dprintk("%s ERROR %d, Reset session\n", __func__,
 -                              task->tk_status);
 -                      nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
 -                      goto wait_on_recovery;
 -#endif /* CONFIG_NFS_V4_1 */
 -              case -NFS4ERR_DELAY:
 -                      nfs_inc_server_stats(server, NFSIOS_DELAY);
 -                      rpc_delay(task, nfs4_update_delay(timeout));
 -                      goto restart_call;
 -              case -NFS4ERR_GRACE:
 -                      rpc_delay(task, NFS4_POLL_RETRY_MAX);
 -              case -NFS4ERR_RETRY_UNCACHED_REP:
 -              case -NFS4ERR_OLD_STATEID:
 -                      goto restart_call;
 -      }
 -      task->tk_status = nfs4_map_errors(task->tk_status);
 -      return 0;
 -recovery_failed:
 -      task->tk_status = -EIO;
 -      return 0;
 -wait_on_recovery:
 -      rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
 -      if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
 -              rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
 -      if (test_bit(NFS_MIG_FAILED, &server->mig_status))
 -              goto recovery_failed;
 -restart_call:
 -      task->tk_status = 0;
 -      return -EAGAIN;
 -}
 -
  static void nfs4_init_boot_verifier(const struct nfs_client *clp,
                                    nfs4_verifier *bootverf)
  {
@@@ -5521,7 -5522,7 +5521,7 @@@ struct nfs4_unlockdata 
        struct nfs4_lock_state *lsp;
        struct nfs_open_context *ctx;
        struct file_lock fl;
 -      const struct nfs_server *server;
 +      struct nfs_server *server;
        unsigned long timestamp;
  };
  
@@@ -6248,9 -6249,10 +6248,10 @@@ nfs4_release_lockowner(struct nfs_serve
  
  #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
  
- static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key,
+ static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler,
+                                  struct dentry *dentry, const char *key,
                                   const void *buf, size_t buflen,
-                                  int flags, int type)
+                                  int flags)
  {
        if (strcmp(key, "") != 0)
                return -EINVAL;
        return nfs4_proc_set_acl(d_inode(dentry), buf, buflen);
  }
  
- static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key,
-                                  void *buf, size_t buflen, int type)
+ static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
+                                  struct dentry *dentry, const char *key,
+                                  void *buf, size_t buflen)
  {
        if (strcmp(key, "") != 0)
                return -EINVAL;
        return nfs4_proc_get_acl(d_inode(dentry), buf, buflen);
  }
  
- static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list,
+ static size_t nfs4_xattr_list_nfs4_acl(const struct xattr_handler *handler,
+                                      struct dentry *dentry, char *list,
                                       size_t list_len, const char *name,
-                                      size_t name_len, int type)
+                                      size_t name_len)
  {
        size_t len = sizeof(XATTR_NAME_NFSV4_ACL);
  
@@@ -6287,9 -6291,10 +6290,10 @@@ static inline int nfs4_server_supports_
        return server->caps & NFS_CAP_SECURITY_LABEL;
  }
  
- static int nfs4_xattr_set_nfs4_label(struct dentry *dentry, const char *key,
-                                  const void *buf, size_t buflen,
-                                  int flags, int type)
+ static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler,
+                                    struct dentry *dentry, const char *key,
+                                    const void *buf, size_t buflen,
+                                    int flags)
  {
        if (security_ismaclabel(key))
                return nfs4_set_security_label(dentry, buf, buflen);
        return -EOPNOTSUPP;
  }
  
- static int nfs4_xattr_get_nfs4_label(struct dentry *dentry, const char *key,
-                                  void *buf, size_t buflen, int type)
+ static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler,
+                                    struct dentry *dentry, const char *key,
+                                    void *buf, size_t buflen)
  {
        if (security_ismaclabel(key))
                return nfs4_get_security_label(d_inode(dentry), buf, buflen);
        return -EOPNOTSUPP;
  }
  
- static size_t nfs4_xattr_list_nfs4_label(struct dentry *dentry, char *list,
-                                      size_t list_len, const char *name,
-                                      size_t name_len, int type)
+ static size_t nfs4_xattr_list_nfs4_label(const struct xattr_handler *handler,
+                                        struct dentry *dentry, char *list,
+                                        size_t list_len, const char *name,
+                                        size_t name_len)
  {
        size_t len = 0;
  
@@@ -8717,8 -8724,7 +8723,8 @@@ static const struct nfs4_minor_version_
                | NFS_CAP_ALLOCATE
                | NFS_CAP_DEALLOCATE
                | NFS_CAP_SEEK
 -              | NFS_CAP_LAYOUTSTATS,
 +              | NFS_CAP_LAYOUTSTATS
 +              | NFS_CAP_CLONE,
        .init_client = nfs41_init_client,
        .shutdown_client = nfs41_shutdown_client,
        .match_stateid = nfs41_match_stateid,
diff --combined fs/ubifs/super.c
index 8ee3133dd8e49af9f413025683236cf464a62f12,c71edca41f4798e6eb0c9db4ed646addf6e36330..1fd90c0795374b6abae3d9787e1b898bd1819546
@@@ -128,10 -128,7 +128,10 @@@ struct inode *ubifs_iget(struct super_b
        if (err)
                goto out_ino;
  
 -      inode->i_flags |= (S_NOCMTIME | S_NOATIME);
 +      inode->i_flags |= S_NOCMTIME;
 +#ifndef CONFIG_UBIFS_ATIME_SUPPORT
 +      inode->i_flags |= S_NOATIME;
 +#endif
        set_nlink(inode, le32_to_cpu(ino->nlink));
        i_uid_write(inode, le32_to_cpu(ino->uid));
        i_gid_write(inode, le32_to_cpu(ino->gid));
@@@ -2040,7 -2037,6 +2040,6 @@@ static int ubifs_fill_super(struct supe
        if (c->max_inode_sz > MAX_LFS_FILESIZE)
                sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
        sb->s_op = &ubifs_super_operations;
-       sb->s_xattr = ubifs_xattr_handlers;
  
        mutex_lock(&c->umount_mutex);
        err = mount_ubifs(c);
@@@ -2142,12 -2138,7 +2141,12 @@@ static struct dentry *ubifs_mount(struc
                if (err)
                        goto out_deact;
                /* We do not support atime */
 -              sb->s_flags |= MS_ACTIVE | MS_NOATIME;
 +              sb->s_flags |= MS_ACTIVE;
 +#ifndef CONFIG_UBIFS_ATIME_SUPPORT
 +              sb->s_flags |= MS_NOATIME;
 +#else
 +              ubifs_msg(c, "full atime support is enabled.");
 +#endif
        }
  
        /* 'fill_super()' opens ubi again so we must close it here */
diff --combined fs/ubifs/ubifs.h
index 01142e129d168ccba3139992ce50df56c9acea3a,33b6ee7b5fe0bcc61cd3e8fa9f00466f6c766491..a5697de763f516f659b7f69e42e5eba4ad94efec
@@@ -858,9 -858,9 +858,9 @@@ struct ubifs_compressor 
   * @mod_dent: non-zero if the operation removes or modifies an existing
   *            directory entry
   * @new_ino: non-zero if the operation adds a new inode
 - * @new_ino_d: now much data newly created inode contains
 + * @new_ino_d: how much data newly created inode contains
   * @dirtied_ino: how many inodes the operation makes dirty
 - * @dirtied_ino_d: now much data dirtied inode contains
 + * @dirtied_ino_d: how much data dirtied inode contains
   * @idx_growth: how much the index will supposedly grow
   * @data_growth: how much new data the operation will supposedly add
   * @dd_growth: how much data that makes other data dirty the operation will
@@@ -1470,7 -1470,6 +1470,6 @@@ extern spinlock_t ubifs_infos_lock
  extern atomic_long_t ubifs_clean_zn_cnt;
  extern struct kmem_cache *ubifs_inode_slab;
  extern const struct super_operations ubifs_super_operations;
- extern const struct xattr_handler *ubifs_xattr_handlers[];
  extern const struct address_space_operations ubifs_file_address_operations;
  extern const struct file_operations ubifs_file_operations;
  extern const struct inode_operations ubifs_file_inode_operations;
@@@ -1746,9 -1745,6 +1745,9 @@@ int ubifs_calc_dark(const struct ubifs_
  /* file.c */
  int ubifs_fsync(struct file *file, loff_t start, loff_t end, int datasync);
  int ubifs_setattr(struct dentry *dentry, struct iattr *attr);
 +#ifdef CONFIG_UBIFS_ATIME_SUPPORT
 +int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
 +#endif
  
  /* dir.c */
  struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
diff --combined fs/ubifs/xattr.c
index 259fbabf143d8cb8cf4e88df59268710fd420137,513815c45a2b1ab6d03bbf600f891c81eb58386c..e8b01b721e99d3954e344686fc615c9455e4246c
@@@ -200,7 -200,6 +200,7 @@@ static int change_xattr(struct ubifs_in
        int err;
        struct ubifs_inode *host_ui = ubifs_inode(host);
        struct ubifs_inode *ui = ubifs_inode(inode);
 +      void *buf = NULL;
        struct ubifs_budget_req req = { .dirtied_ino = 2,
                .dirtied_ino_d = ALIGN(size, 8) + ALIGN(host_ui->data_len, 8) };
  
        if (err)
                return err;
  
 -      kfree(ui->data);
 -      ui->data = kmemdup(value, size, GFP_NOFS);
 -      if (!ui->data) {
 +      buf = kmemdup(value, size, GFP_NOFS);
 +      if (!buf) {
                err = -ENOMEM;
                goto out_free;
        }
 +      mutex_lock(&ui->ui_mutex);
 +      kfree(ui->data);
 +      ui->data = buf;
        inode->i_size = ui->ui_size = size;
        ui->data_len = size;
 +      mutex_unlock(&ui->ui_mutex);
  
        mutex_lock(&host_ui->ui_mutex);
        host->i_ctime = ubifs_current_time(host);
@@@ -413,7 -409,6 +413,7 @@@ ssize_t ubifs_getxattr(struct dentry *d
        ubifs_assert(inode->i_size == ui->data_len);
        ubifs_assert(ubifs_inode(host)->xattr_size > ui->data_len);
  
 +      mutex_lock(&ui->ui_mutex);
        if (buf) {
                /* If @buf is %NULL we are supposed to return the length */
                if (ui->data_len > size) {
        err = ui->data_len;
  
  out_iput:
 +      mutex_unlock(&ui->ui_mutex);
        iput(inode);
  out_unlock:
        kfree(xent);
@@@ -588,46 -582,6 +588,6 @@@ out_free
        return err;
  }
  
- static size_t security_listxattr(struct dentry *d, char *list, size_t list_size,
-                                const char *name, size_t name_len, int flags)
- {
-       const int prefix_len = XATTR_SECURITY_PREFIX_LEN;
-       const size_t total_len = prefix_len + name_len + 1;
-       if (list && total_len <= list_size) {
-               memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
-               memcpy(list + prefix_len, name, name_len);
-               list[prefix_len + name_len] = '\0';
-       }
-       return total_len;
- }
- static int security_getxattr(struct dentry *d, const char *name, void *buffer,
-                     size_t size, int flags)
- {
-       return ubifs_getxattr(d, name, buffer, size);
- }
- static int security_setxattr(struct dentry *d, const char *name,
-                            const void *value, size_t size, int flags,
-                            int handler_flags)
- {
-       return ubifs_setxattr(d, name, value, size, flags);
- }
- static const struct xattr_handler ubifs_xattr_security_handler = {
-       .prefix = XATTR_SECURITY_PREFIX,
-       .list   = security_listxattr,
-       .get    = security_getxattr,
-       .set    = security_setxattr,
- };
- const struct xattr_handler *ubifs_xattr_handlers[] = {
-       &ubifs_xattr_security_handler,
-       NULL,
- };
  static int init_xattrs(struct inode *inode, const struct xattr *xattr_array,
                      void *fs_info)
  {
diff --combined fs/xfs/xfs_xattr.c
index 8294f86441bfcdc108eb28ec57b7a449f31dd675,b1850e1489ef6e2c17b8bc3eef905cfc741178c1..839b35ca21c69320c736ac636ef681b1362402ce
  
  
  static int
- xfs_xattr_get(struct dentry *dentry, const char *name,
-               void *value, size_t size, int xflags)
+ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry,
+               const char *name, void *value, size_t size)
  {
+       int xflags = handler->flags;
        struct xfs_inode *ip = XFS_I(d_inode(dentry));
        int error, asize = size;
  
        return asize;
  }
  
 +void
 +xfs_forget_acl(
 +      struct inode            *inode,
 +      const char              *name,
 +      int                     xflags)
 +{
 +      /*
 +       * Invalidate any cached ACLs if the user has bypassed the ACL
 +       * interface. We don't validate the content whatsoever so it is caller
 +       * responsibility to provide data in valid format and ensure i_mode is
 +       * consistent.
 +       */
 +      if (xflags & ATTR_ROOT) {
 +#ifdef CONFIG_XFS_POSIX_ACL
 +              if (!strcmp(name, SGI_ACL_FILE))
 +                      forget_cached_acl(inode, ACL_TYPE_ACCESS);
 +              else if (!strcmp(name, SGI_ACL_DEFAULT))
 +                      forget_cached_acl(inode, ACL_TYPE_DEFAULT);
 +#endif
 +      }
 +}
 +
  static int
- xfs_xattr_set(struct dentry *dentry, const char *name, const void *value,
-               size_t size, int flags, int xflags)
+ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry,
+               const char *name, const void *value, size_t size, int flags)
  {
 -      int xflags = handler->flags;
 -      struct xfs_inode *ip = XFS_I(d_inode(dentry));
++      int                     xflags = handler->flags;
 +      struct xfs_inode        *ip = XFS_I(d_inode(dentry));
 +      int                     error;
  
        if (strcmp(name, "") == 0)
                return -EINVAL;
  
        if (!value)
                return xfs_attr_remove(ip, (unsigned char *)name, xflags);
 -      return xfs_attr_set(ip, (unsigned char *)name,
 +      error = xfs_attr_set(ip, (unsigned char *)name,
                                (void *)value, size, xflags);
 +      if (!error)
 +              xfs_forget_acl(d_inode(dentry), name, xflags);
 +
 +      return error;
  }
  
  static const struct xattr_handler xfs_xattr_user_handler = {