]> Git Repo - linux.git/commitdiff
Merge tag 'gfs2-for-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux...
authorLinus Torvalds <[email protected]>
Tue, 23 Feb 2021 22:04:04 +0000 (14:04 -0800)
committerLinus Torvalds <[email protected]>
Tue, 23 Feb 2021 22:04:04 +0000 (14:04 -0800)
Pull gfs2 updates from Andreas Gruenbacher:

 - Log space and revoke accounting rework to fix some failed asserts.

 - Local resource group glock sharing for better local performance.

 - Add support for version 1802 filesystems: trusted xattr support and
   '-o rgrplvb' mounts by default.

 - Actually synchronize on the inode glock's FREEING bit during withdraw
   ("gfs2: fix glock confusion in function signal_our_withdraw").

 - Fix parallel recovery of multiple journals ("gfs2: keep bios separate
   for each journal").

 - Various other bug fixes.

* tag 'gfs2-for-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: (49 commits)
  gfs2: Don't get stuck with I/O plugged in gfs2_ail1_flush
  gfs2: Per-revoke accounting in transactions
  gfs2: Rework the log space allocation logic
  gfs2: Minor calc_reserved cleanup
  gfs2: Use resource group glock sharing
  gfs2: Allow node-wide exclusive glock sharing
  gfs2: Add local resource group locking
  gfs2: Add per-reservation reserved block accounting
  gfs2: Rename rs_{free -> requested} and rd_{reserved -> requested}
  gfs2: Check for active reservation in gfs2_release
  gfs2: Don't search for unreserved space twice
  gfs2: Only pass reservation down to gfs2_rbm_find
  gfs2: Also reflect single-block allocations in rgd->rd_extfail_pt
  gfs2: Recursive gfs2_quota_hold in gfs2_iomap_end
  gfs2: Add trusted xattr support
  gfs2: Enable rgrplvb for sb_fs_format 1802
  gfs2: Don't skip dlm unlock if glock has an lvb
  gfs2: Lock imbalance on error path in gfs2_recover_one
  gfs2: Move function gfs2_ail_empty_tr
  gfs2: Get rid of current_tail()
  ...

1  2 
fs/gfs2/file.c
fs/gfs2/inode.c
fs/gfs2/super.c
fs/gfs2/xattr.c

diff --combined fs/gfs2/file.c
index 95bbdd4bca78a8440e4c21cdd59a9b8f208009ce,294087516ce0e13b4bf4e30e56ee2ae0ebb24da3..2d500f90cdacf3ae539ad7ab1905be79def0491d
@@@ -238,7 -238,7 +238,7 @@@ static int do_gfs2_set_flags(struct fil
                goto out;
  
        error = -EACCES;
 -      if (!inode_owner_or_capable(inode))
 +      if (!inode_owner_or_capable(&init_user_ns, inode))
                goto out;
  
        error = 0;
            !capable(CAP_LINUX_IMMUTABLE))
                goto out;
        if (!IS_IMMUTABLE(inode)) {
 -              error = gfs2_permission(inode, MAY_WRITE);
 +              error = gfs2_permission(&init_user_ns, inode, MAY_WRITE);
                if (error)
                        goto out;
        }
@@@ -716,10 -716,10 +716,10 @@@ static int gfs2_release(struct inode *i
        kfree(file->private_data);
        file->private_data = NULL;
  
-       if (file->f_mode & FMODE_WRITE) {
+       if (gfs2_rs_active(&ip->i_res))
                gfs2_rs_delete(ip, &inode->i_writecount);
+       if (file->f_mode & FMODE_WRITE)
                gfs2_qa_put(ip);
-       }
        return 0;
  }
  
@@@ -749,7 -749,7 +749,7 @@@ static int gfs2_fsync(struct file *file
  {
        struct address_space *mapping = file->f_mapping;
        struct inode *inode = mapping->host;
 -      int sync_state = inode->i_state & I_DIRTY_ALL;
 +      int sync_state = inode->i_state & I_DIRTY;
        struct gfs2_inode *ip = GFS2_I(inode);
        int ret = 0, ret1 = 0;
  
        if (!gfs2_is_jdata(ip))
                sync_state &= ~I_DIRTY_PAGES;
        if (datasync)
 -              sync_state &= ~(I_DIRTY_SYNC | I_DIRTY_TIME);
 +              sync_state &= ~I_DIRTY_SYNC;
  
        if (sync_state) {
                ret = sync_inode_metadata(inode, 1);
@@@ -797,7 -797,9 +797,7 @@@ static ssize_t gfs2_file_direct_read(st
        if (ret)
                goto out_uninit;
  
 -      ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL,
 -                         is_sync_kiocb(iocb));
 -
 +      ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL, 0);
        gfs2_glock_dq(gh);
  out_uninit:
        gfs2_holder_uninit(gh);
@@@ -831,7 -833,8 +831,7 @@@ static ssize_t gfs2_file_direct_write(s
        if (offset + len > i_size_read(&ip->i_inode))
                goto out;
  
 -      ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL,
 -                         is_sync_kiocb(iocb));
 +      ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL, 0);
        if (ret == -ENOTBLK)
                ret = 0;
  out:
@@@ -1112,8 -1115,8 +1112,8 @@@ static long __gfs2_fallocate(struct fil
                        goto out_qunlock;
  
                /* check if the selected rgrp limits our max_blks further */
-               if (ap.allowed && ap.allowed < max_blks)
-                       max_blks = ap.allowed;
+               if (ip->i_res.rs_reserved < max_blks)
+                       max_blks = ip->i_res.rs_reserved;
  
                /* Almost done. Calculate bytes that can be written using
                 * max_blks. We also recompute max_bytes, data_blocks and
diff --combined fs/gfs2/inode.c
index cfac2c1e67fa0a01d73a14793c4765d77a309fdd,4d3d8624a95be13065950a501e6d5ebcb3b7f0a9..68376fa038807e7d4a5ccc4d673148e1c53876d3
@@@ -325,7 -325,7 +325,7 @@@ struct inode *gfs2_lookupi(struct inod
        }
  
        if (!is_root) {
 -              error = gfs2_permission(dir, MAY_EXEC);
 +              error = gfs2_permission(&init_user_ns, dir, MAY_EXEC);
                if (error)
                        goto out;
        }
@@@ -355,8 -355,7 +355,8 @@@ static int create_ok(struct gfs2_inode 
  {
        int error;
  
 -      error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC);
 +      error = gfs2_permission(&init_user_ns, &dip->i_inode,
 +                              MAY_WRITE | MAY_EXEC);
        if (error)
                return error;
  
@@@ -844,8 -843,8 +844,8 @@@ fail
   * Returns: errno
   */
  
 -static int gfs2_create(struct inode *dir, struct dentry *dentry,
 -                     umode_t mode, bool excl)
 +static int gfs2_create(struct user_namespace *mnt_userns, struct inode *dir,
 +                     struct dentry *dentry, umode_t mode, bool excl)
  {
        return gfs2_create_inode(dir, dentry, NULL, S_IFREG | mode, 0, NULL, 0, excl);
  }
@@@ -952,7 -951,7 +952,7 @@@ static int gfs2_link(struct dentry *old
        if (inode->i_nlink == 0)
                goto out_gunlock;
  
 -      error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC);
 +      error = gfs2_permission(&init_user_ns, dir, MAY_WRITE | MAY_EXEC);
        if (error)
                goto out_gunlock;
  
@@@ -1069,8 -1068,7 +1069,8 @@@ static int gfs2_unlink_ok(struct gfs2_i
        if (IS_APPEND(&dip->i_inode))
                return -EPERM;
  
 -      error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC);
 +      error = gfs2_permission(&init_user_ns, &dip->i_inode,
 +                              MAY_WRITE | MAY_EXEC);
        if (error)
                return error;
  
@@@ -1147,7 -1145,7 +1147,7 @@@ static int gfs2_unlink(struct inode *di
        if (!rgd)
                goto out_inodes;
  
-       gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
+       gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, LM_FLAG_NODE_SCOPE, ghs + 2);
  
  
        error = gfs2_glock_nq(ghs); /* parent */
@@@ -1206,8 -1204,8 +1206,8 @@@ out_inodes
   * Returns: errno
   */
  
 -static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
 -                      const char *symname)
 +static int gfs2_symlink(struct user_namespace *mnt_userns, struct inode *dir,
 +                      struct dentry *dentry, const char *symname)
  {
        unsigned int size;
  
   * Returns: errno
   */
  
 -static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 +static int gfs2_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
 +                    struct dentry *dentry, umode_t mode)
  {
        unsigned dsize = gfs2_max_stuffed_size(GFS2_I(dir));
        return gfs2_create_inode(dir, dentry, NULL, S_IFDIR | mode, 0, NULL, dsize, 0);
   *
   */
  
 -static int gfs2_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
 -                    dev_t dev)
 +static int gfs2_mknod(struct user_namespace *mnt_userns, struct inode *dir,
 +                    struct dentry *dentry, umode_t mode, dev_t dev)
  {
        return gfs2_create_inode(dir, dentry, NULL, mode, dev, NULL, 0, 0);
  }
@@@ -1453,8 -1450,8 +1453,8 @@@ static int gfs2_rename(struct inode *od
                        error = -ENOENT;
                        goto out_gunlock;
                }
-               error = gfs2_glock_nq_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0,
-                                          &rd_gh);
+               error = gfs2_glock_nq_init(nrgd->rd_gl, LM_ST_EXCLUSIVE,
+                                          LM_FLAG_NODE_SCOPE, &rd_gh);
                if (error)
                        goto out_gunlock;
        }
                        }
                }
        } else {
 -              error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC);
 +              error = gfs2_permission(&init_user_ns, ndir,
 +                                      MAY_WRITE | MAY_EXEC);
                if (error)
                        goto out_gunlock;
  
        /* Check out the dir to be renamed */
  
        if (dir_rename) {
 -              error = gfs2_permission(d_inode(odentry), MAY_WRITE);
 +              error = gfs2_permission(&init_user_ns, d_inode(odentry),
 +                                      MAY_WRITE);
                if (error)
                        goto out_gunlock;
        }
@@@ -1693,14 -1688,12 +1693,14 @@@ static int gfs2_exchange(struct inode *
                goto out_gunlock;
  
        if (S_ISDIR(old_mode)) {
 -              error = gfs2_permission(odentry->d_inode, MAY_WRITE);
 +              error = gfs2_permission(&init_user_ns, odentry->d_inode,
 +                                      MAY_WRITE);
                if (error)
                        goto out_gunlock;
        }
        if (S_ISDIR(new_mode)) {
 -              error = gfs2_permission(ndentry->d_inode, MAY_WRITE);
 +              error = gfs2_permission(&init_user_ns, ndentry->d_inode,
 +                                      MAY_WRITE);
                if (error)
                        goto out_gunlock;
        }
@@@ -1754,9 -1747,9 +1754,9 @@@ out
        return error;
  }
  
 -static int gfs2_rename2(struct inode *odir, struct dentry *odentry,
 -                      struct inode *ndir, struct dentry *ndentry,
 -                      unsigned int flags)
 +static int gfs2_rename2(struct user_namespace *mnt_userns, struct inode *odir,
 +                      struct dentry *odentry, struct inode *ndir,
 +                      struct dentry *ndentry, unsigned int flags)
  {
        flags &= ~RENAME_NOREPLACE;
  
@@@ -1840,8 -1833,7 +1840,8 @@@ out
   * Returns: errno
   */
  
 -int gfs2_permission(struct inode *inode, int mask)
 +int gfs2_permission(struct user_namespace *mnt_userns, struct inode *inode,
 +                  int mask)
  {
        struct gfs2_inode *ip;
        struct gfs2_holder i_gh;
        if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
                error = -EPERM;
        else
 -              error = generic_permission(inode, mask);
 +              error = generic_permission(&init_user_ns, inode, mask);
        if (gfs2_holder_initialized(&i_gh))
                gfs2_glock_dq_uninit(&i_gh);
  
  
  static int __gfs2_setattr_simple(struct inode *inode, struct iattr *attr)
  {
 -      setattr_copy(inode, attr);
 +      setattr_copy(&init_user_ns, inode, attr);
        mark_inode_dirty(inode);
        return 0;
  }
@@@ -1971,8 -1963,7 +1971,8 @@@ out
   * Returns: errno
   */
  
 -static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
 +static int gfs2_setattr(struct user_namespace *mnt_userns,
 +                      struct dentry *dentry, struct iattr *attr)
  {
        struct inode *inode = d_inode(dentry);
        struct gfs2_inode *ip = GFS2_I(inode);
        if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                goto error;
  
 -      error = setattr_prepare(dentry, attr);
 +      error = setattr_prepare(&init_user_ns, dentry, attr);
        if (error)
                goto error;
  
        else {
                error = gfs2_setattr_simple(inode, attr);
                if (!error && attr->ia_valid & ATTR_MODE)
 -                      error = posix_acl_chmod(inode, inode->i_mode);
 +                      error = posix_acl_chmod(&init_user_ns, inode,
 +                                              inode->i_mode);
        }
  
  error:
@@@ -2017,7 -2007,6 +2017,7 @@@ out
  
  /**
   * gfs2_getattr - Read out an inode's attributes
 + * @mnt_userns:       user namespace of the mount the inode was found from
   * @path: Object to query
   * @stat: The inode's stats
   * @request_mask: Mask of STATX_xxx flags indicating the caller's interests
   * Returns: errno
   */
  
 -static int gfs2_getattr(const struct path *path, struct kstat *stat,
 +static int gfs2_getattr(struct user_namespace *mnt_userns,
 +                      const struct path *path, struct kstat *stat,
                        u32 request_mask, unsigned int flags)
  {
        struct inode *inode = d_inode(path->dentry);
                                  STATX_ATTR_IMMUTABLE |
                                  STATX_ATTR_NODUMP);
  
 -      generic_fillattr(inode, stat);
 +      generic_fillattr(&init_user_ns, inode, stat);
  
        if (gfs2_holder_initialized(&gh))
                gfs2_glock_dq_uninit(&gh);
diff --combined fs/gfs2/super.c
index 042b94288ff11ad7349bf3eab2fa42d5de268be4,7aa602a0ef1b00cfc725f8cea1bd0385bb037287..861ed5fe02a59dc786d781265183bc3ec9cf2051
@@@ -81,19 -81,12 +81,12 @@@ void gfs2_jindex_free(struct gfs2_sbd *
  static struct gfs2_jdesc *jdesc_find_i(struct list_head *head, unsigned int jid)
  {
        struct gfs2_jdesc *jd;
-       int found = 0;
  
        list_for_each_entry(jd, head, jd_list) {
-               if (jd->jd_jid == jid) {
-                       found = 1;
-                       break;
-               }
+               if (jd->jd_jid == jid)
+                       return jd;
        }
-       if (!found)
-               jd = NULL;
-       return jd;
+       return NULL;
  }
  
  struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid)
@@@ -165,7 -158,6 +158,6 @@@ int gfs2_make_fs_rw(struct gfs2_sbd *sd
  {
        struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
        struct gfs2_glock *j_gl = ip->i_gl;
-       struct gfs2_holder freeze_gh;
        struct gfs2_log_header_host head;
        int error;
  
        if (error)
                return error;
  
-       error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
-                                  LM_FLAG_NOEXP | GL_EXACT,
-                                  &freeze_gh);
-       if (error)
-               goto fail_threads;
        j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
        if (gfs2_withdrawn(sdp)) {
                error = -EIO;
  
        set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
  
-       gfs2_glock_dq_uninit(&freeze_gh);
        return 0;
  
  fail:
-       gfs2_glock_dq_uninit(&freeze_gh);
- fail_threads:
        if (sdp->sd_quotad_process)
                kthread_stop(sdp->sd_quotad_process);
        sdp->sd_quotad_process = NULL;
@@@ -452,7 -434,7 +434,7 @@@ static int gfs2_lock_fs_check_clean(str
        }
  
        if (error)
-               gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
+               gfs2_freeze_unlock(&sdp->sd_freeze_gh);
  
  out:
        while (!list_empty(&list)) {
@@@ -562,6 -544,8 +544,6 @@@ static void gfs2_dirty_inode(struct ino
        int need_endtrans = 0;
        int ret;
  
 -      if (!(flags & I_DIRTY_INODE))
 -              return;
        if (unlikely(gfs2_withdrawn(sdp)))
                return;
        if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
@@@ -607,30 -591,9 +589,9 @@@ out
  
  int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
  {
-       struct gfs2_holder freeze_gh;
        int error = 0;
        int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
  
-       gfs2_holder_mark_uninitialized(&freeze_gh);
-       if (sdp->sd_freeze_gl &&
-           !gfs2_glock_is_locked_by_me(sdp->sd_freeze_gl)) {
-               if (!log_write_allowed) {
-                       error = gfs2_glock_nq_init(sdp->sd_freeze_gl,
-                                                  LM_ST_SHARED, LM_FLAG_TRY |
-                                                  LM_FLAG_NOEXP | GL_EXACT,
-                                                  &freeze_gh);
-                       if (error == GLR_TRYFAILED)
-                               error = 0;
-               } else {
-                       error = gfs2_glock_nq_init(sdp->sd_freeze_gl,
-                                                  LM_ST_SHARED,
-                                                  LM_FLAG_NOEXP | GL_EXACT,
-                                                  &freeze_gh);
-                       if (error && !gfs2_withdrawn(sdp))
-                               return error;
-               }
-       }
        gfs2_flush_delete_work(sdp);
        if (!log_write_allowed && current == sdp->sd_quotad_process)
                fs_warn(sdp, "The quotad daemon is withdrawing.\n");
  
                gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SHUTDOWN |
                               GFS2_LFC_MAKE_FS_RO);
-               wait_event(sdp->sd_reserving_log_wait,
-                          atomic_read(&sdp->sd_reserving_log) == 0);
-               gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) ==
-                                sdp->sd_jdesc->jd_blocks);
+               wait_event_timeout(sdp->sd_log_waitq,
+                                  gfs2_log_is_empty(sdp),
+                                  HZ * 5);
+               gfs2_assert_warn(sdp, gfs2_log_is_empty(sdp));
        } else {
-               wait_event_timeout(sdp->sd_reserving_log_wait,
-                                  atomic_read(&sdp->sd_reserving_log) == 0,
+               wait_event_timeout(sdp->sd_log_waitq,
+                                  gfs2_log_is_empty(sdp),
                                   HZ * 5);
        }
-       if (gfs2_holder_initialized(&freeze_gh))
-               gfs2_glock_dq_uninit(&freeze_gh);
        gfs2_quota_cleanup(sdp);
  
        if (!log_write_allowed)
@@@ -770,10 -730,8 +728,8 @@@ void gfs2_freeze_func(struct work_struc
        struct super_block *sb = sdp->sd_vfs;
  
        atomic_inc(&sb->s_active);
-       error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
-                                  LM_FLAG_NOEXP | GL_EXACT, &freeze_gh);
+       error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
        if (error) {
-               fs_info(sdp, "GFS2: couldn't get freeze lock : %d\n", error);
                gfs2_assert_withdraw(sdp, 0);
        } else {
                atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN);
                                error);
                        gfs2_assert_withdraw(sdp, 0);
                }
-               gfs2_glock_dq_uninit(&freeze_gh);
+               gfs2_freeze_unlock(&freeze_gh);
        }
        deactivate_super(sb);
        clear_bit_unlock(SDF_FS_FROZEN, &sdp->sd_flags);
@@@ -851,7 -809,7 +807,7 @@@ static int gfs2_unfreeze(struct super_b
                  return 0;
        }
  
-       gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
+       gfs2_freeze_unlock(&sdp->sd_freeze_gh);
        mutex_unlock(&sdp->sd_freeze_mutex);
        return wait_on_bit(&sdp->sd_flags, SDF_FS_FROZEN, TASK_INTERRUPTIBLE);
  }
@@@ -1227,7 -1185,8 +1183,8 @@@ static int gfs2_dinode_dealloc(struct g
                goto out_qs;
        }
  
-       error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &gh);
+       error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
+                                  LM_FLAG_NODE_SCOPE, &gh);
        if (error)
                goto out_qs;
  
diff --combined fs/gfs2/xattr.c
index 13969a813410574478015d3a9e909bc89b1163b3,a1b9c96cb8ef218426e9d55ed013bb10fd59570e..124b3d5a7266539fde1b4fdc6ad84c9a1f2b80da
@@@ -70,6 -70,20 +70,20 @@@ static int ea_check_size(struct gfs2_sb
        return 0;
  }
  
+ static bool gfs2_eatype_valid(struct gfs2_sbd *sdp, u8 type)
+ {
+       switch(sdp->sd_sb.sb_fs_format) {
+       case GFS2_FS_FORMAT_MAX:
+               return true;
+       case GFS2_FS_FORMAT_MIN:
+               return type <= GFS2_EATYPE_SECURITY;
+       default:
+               return false;
+       }
+ }
  typedef int (*ea_call_t) (struct gfs2_inode *ip, struct buffer_head *bh,
                          struct gfs2_ea_header *ea,
                          struct gfs2_ea_header *prev, void *private);
@@@ -77,6 -91,7 +91,7 @@@
  static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
                        ea_call_t ea_call, void *data)
  {
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_ea_header *ea, *prev = NULL;
        int error = 0;
  
                if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <=
                                                  bh->b_data + bh->b_size))
                        goto fail;
-               if (!GFS2_EATYPE_VALID(ea->ea_type))
+               if (!gfs2_eatype_valid(sdp, ea->ea_type))
                        goto fail;
                error = ea_call(ip, bh, ea, prev, data);
                if (error)
                        return error;
@@@ -259,7 -273,8 +273,8 @@@ static int ea_dealloc_unstuffed(struct 
                return -EIO;
        }
  
-       error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh);
+       error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
+                                  LM_FLAG_NODE_SCOPE, &rg_gh);
        if (error)
                return error;
  
@@@ -344,6 -359,7 +359,7 @@@ static int ea_list_i(struct gfs2_inode 
                     struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
                     void *private)
  {
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct ea_list *ei = private;
        struct gfs2_ea_request *er = ei->ei_er;
        unsigned int ea_size;
        if (ea->ea_type == GFS2_EATYPE_UNUSED)
                return 0;
  
+       BUG_ON(ea->ea_type > GFS2_EATYPE_SECURITY &&
+              sdp->sd_sb.sb_fs_format == GFS2_FS_FORMAT_MIN);
        switch (ea->ea_type) {
        case GFS2_EATYPE_USR:
                prefix = "user.";
                prefix = "security.";
                l = 9;
                break;
+       case GFS2_EATYPE_TRUSTED:
+               prefix = "trusted.";
+               l = 8;
+               break;
        default:
-               BUG();
+               return 0;
        }
  
        ea_size = l + ea->ea_name_len + 1;
@@@ -1214,7 -1236,6 +1236,7 @@@ int __gfs2_xattr_set(struct inode *inod
  }
  
  static int gfs2_xattr_set(const struct xattr_handler *handler,
 +                        struct user_namespace *mnt_userns,
                          struct dentry *unused, struct inode *inode,
                          const char *name, const void *value,
                          size_t size, int flags)
@@@ -1386,7 -1407,8 +1408,8 @@@ static int ea_dealloc_block(struct gfs2
                return -EIO;
        }
  
-       error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &gh);
+       error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE,
+                                  LM_FLAG_NODE_SCOPE, &gh);
        if (error)
                return error;
  
@@@ -1464,7 -1486,25 +1487,25 @@@ static const struct xattr_handler gfs2_
        .set    = gfs2_xattr_set,
  };
  
- const struct xattr_handler *gfs2_xattr_handlers[] = {
+ static bool
+ gfs2_xattr_trusted_list(struct dentry *dentry)
+ {
+       return capable(CAP_SYS_ADMIN);
+ }
+ static const struct xattr_handler gfs2_xattr_trusted_handler = {
+       .prefix = XATTR_TRUSTED_PREFIX,
+       .flags  = GFS2_EATYPE_TRUSTED,
+       .list   = gfs2_xattr_trusted_list,
+       .get    = gfs2_xattr_get,
+       .set    = gfs2_xattr_set,
+ };
+ const struct xattr_handler *gfs2_xattr_handlers_max[] = {
+       /* GFS2_FS_FORMAT_MAX */
+       &gfs2_xattr_trusted_handler,
+       /* GFS2_FS_FORMAT_MIN */
        &gfs2_xattr_user_handler,
        &gfs2_xattr_security_handler,
        &posix_acl_access_xattr_handler,
        NULL,
  };
  
+ const struct xattr_handler **gfs2_xattr_handlers_min = gfs2_xattr_handlers_max + 1;
This page took 0.101796 seconds and 4 git commands to generate.