]> git.dujemihanovic.xyz Git - linux.git/commitdiff
Merge tag 'pull-stable-struct_fd' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 23 Sep 2024 16:35:36 +0000 (09:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 23 Sep 2024 16:35:36 +0000 (09:35 -0700)
Pull 'struct fd' updates from Al Viro:
 "Just the 'struct fd' layout change, with conversion to accessor
  helpers"

* tag 'pull-stable-struct_fd' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  add struct fd constructors, get rid of __to_fd()
  struct fd: representation change
  introduce fd_file(), convert all accessors to it.

38 files changed:
1  2 
arch/alpha/kernel/osf_sys.c
arch/x86/kernel/cpu/sgx/main.c
arch/x86/kvm/svm/sev.c
drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c
drivers/gpu/drm/drm_syncobj.c
fs/btrfs/ioctl.c
fs/eventpoll.c
fs/fcntl.c
fs/fhandle.c
fs/file.c
fs/fuse/dev.c
fs/locks.c
fs/namei.c
fs/namespace.c
fs/open.c
fs/read_write.c
fs/select.c
fs/signalfd.c
fs/smb/client/ioctl.c
fs/xfs/xfs_exchrange.c
fs/xfs/xfs_ioctl.c
include/linux/file.h
io_uring/sqpoll.c
kernel/bpf/btf.c
kernel/bpf/syscall.c
kernel/cgroup/cgroup.c
kernel/events/core.c
kernel/module/main.c
kernel/signal.c
kernel/sys.c
mm/filemap.c
mm/memcontrol-v1.c
mm/readahead.c
net/core/net_namespace.c
net/socket.c
security/integrity/ima/ima_main.c
sound/core/pcm_native.c
virt/kvm/eventfd.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc fs/eventpoll.c
Simple merge
diff --cc fs/fcntl.c
index 081e5e3d89ea3c64eda138f9841d0a149c0b7411,2b56167623546de27aac6ae45c9e1e1de279601a..22dd9dcce7ecc8536afd9dd59b8aaf4644babb29
@@@ -405,39 -340,9 +405,39 @@@ static long f_dupfd_query(int fd, struc
         * overkill, but given our lockless file pointer lookup, the
         * alternatives are complicated.
         */
-       return f.file == filp;
+       return fd_file(f) == filp;
  }
  
 +/* Let the caller figure out whether a given file was just created. */
 +static long f_created_query(const struct file *filp)
 +{
 +      return !!(filp->f_mode & FMODE_CREATED);
 +}
 +
 +static int f_owner_sig(struct file *filp, int signum, bool setsig)
 +{
 +      int ret = 0;
 +      struct fown_struct *f_owner;
 +
 +      might_sleep();
 +
 +      if (setsig) {
 +              if (!valid_signal(signum))
 +                      return -EINVAL;
 +
 +              ret = file_f_owner_allocate(filp);
 +              if (ret)
 +                      return ret;
 +      }
 +
 +      f_owner = file_f_owner(filp);
 +      if (setsig)
 +              f_owner->signum = signum;
 +      else if (f_owner)
 +              ret = f_owner->signum;
 +      return ret;
 +}
 +
  static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
                struct file *filp)
  {
diff --cc fs/fhandle.c
Simple merge
diff --cc fs/file.c
Simple merge
diff --cc fs/fuse/dev.c
Simple merge
diff --cc fs/locks.c
Simple merge
diff --cc fs/namei.c
Simple merge
diff --cc fs/namespace.c
index e71e4564987ba187d2cf1761da1b043212ee3085,c46d48bb38cda6111120e123e4a32d77390371eb..6ba9c434cc9f7abff6e4e096564dda8660c85be5
@@@ -5278,37 -5243,12 +5278,37 @@@ static int copy_mnt_id_req(const struc
   * that, or if not simply grab a passive reference on our mount namespace and
   * return that.
   */
 -static struct mnt_namespace *grab_requested_mnt_ns(u64 mnt_ns_id)
 +static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq)
  {
 -      if (mnt_ns_id)
 -              return lookup_mnt_ns(mnt_ns_id);
 -      refcount_inc(&current->nsproxy->mnt_ns->passive);
 -      return current->nsproxy->mnt_ns;
 +      struct mnt_namespace *mnt_ns;
 +
 +      if (kreq->mnt_ns_id && kreq->spare)
 +              return ERR_PTR(-EINVAL);
 +
 +      if (kreq->mnt_ns_id)
 +              return lookup_mnt_ns(kreq->mnt_ns_id);
 +
 +      if (kreq->spare) {
 +              struct ns_common *ns;
 +
 +              CLASS(fd, f)(kreq->spare);
-               if (!f.file)
++              if (fd_empty(f))
 +                      return ERR_PTR(-EBADF);
 +
-               if (!proc_ns_file(f.file))
++              if (!proc_ns_file(fd_file(f)))
 +                      return ERR_PTR(-EINVAL);
 +
-               ns = get_proc_ns(file_inode(f.file));
++              ns = get_proc_ns(file_inode(fd_file(f)));
 +              if (ns->ops->type != CLONE_NEWNS)
 +                      return ERR_PTR(-EINVAL);
 +
 +              mnt_ns = to_mnt_ns(ns);
 +      } else {
 +              mnt_ns = current->nsproxy->mnt_ns;
 +      }
 +
 +      refcount_inc(&mnt_ns->passive);
 +      return mnt_ns;
  }
  
  SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
diff --cc fs/open.c
Simple merge
diff --cc fs/read_write.c
Simple merge
diff --cc fs/select.c
Simple merge
diff --cc fs/signalfd.c
Simple merge
Simple merge
index d0889190ab7ff5b01497f19c2ecefa5956d1eba2,9790e0f45d147463c90eaa102a43d1233a9373fb..75cb53f090d1f7c6729ebac07598cc0238d27943
@@@ -837,109 -802,3 +837,109 @@@ xfs_ioc_exchange_range
        fdput(file1);
        return error;
  }
-       if (!file1.file)
 +
 +/* Opaque freshness blob for XFS_IOC_COMMIT_RANGE */
 +struct xfs_commit_range_fresh {
 +      xfs_fsid_t      fsid;           /* m_fixedfsid */
 +      __u64           file2_ino;      /* inode number */
 +      __s64           file2_mtime;    /* modification time */
 +      __s64           file2_ctime;    /* change time */
 +      __s32           file2_mtime_nsec; /* mod time, nsec */
 +      __s32           file2_ctime_nsec; /* change time, nsec */
 +      __u32           file2_gen;      /* inode generation */
 +      __u32           magic;          /* zero */
 +};
 +#define XCR_FRESH_MAGIC       0x444F524B      /* DORK */
 +
 +/* Set up a commitrange operation by sampling file2's write-related attrs */
 +long
 +xfs_ioc_start_commit(
 +      struct file                     *file,
 +      struct xfs_commit_range __user  *argp)
 +{
 +      struct xfs_commit_range         args = { };
 +      struct timespec64               ts;
 +      struct xfs_commit_range_fresh   *kern_f;
 +      struct xfs_commit_range_fresh   __user *user_f;
 +      struct inode                    *inode2 = file_inode(file);
 +      struct xfs_inode                *ip2 = XFS_I(inode2);
 +      const unsigned int              lockflags = XFS_IOLOCK_SHARED |
 +                                                  XFS_MMAPLOCK_SHARED |
 +                                                  XFS_ILOCK_SHARED;
 +
 +      BUILD_BUG_ON(sizeof(struct xfs_commit_range_fresh) !=
 +                   sizeof(args.file2_freshness));
 +
 +      kern_f = (struct xfs_commit_range_fresh *)&args.file2_freshness;
 +
 +      memcpy(&kern_f->fsid, ip2->i_mount->m_fixedfsid, sizeof(xfs_fsid_t));
 +
 +      xfs_ilock(ip2, lockflags);
 +      ts = inode_get_ctime(inode2);
 +      kern_f->file2_ctime             = ts.tv_sec;
 +      kern_f->file2_ctime_nsec        = ts.tv_nsec;
 +      ts = inode_get_mtime(inode2);
 +      kern_f->file2_mtime             = ts.tv_sec;
 +      kern_f->file2_mtime_nsec        = ts.tv_nsec;
 +      kern_f->file2_ino               = ip2->i_ino;
 +      kern_f->file2_gen               = inode2->i_generation;
 +      kern_f->magic                   = XCR_FRESH_MAGIC;
 +      xfs_iunlock(ip2, lockflags);
 +
 +      user_f = (struct xfs_commit_range_fresh __user *)&argp->file2_freshness;
 +      if (copy_to_user(user_f, kern_f, sizeof(*kern_f)))
 +              return -EFAULT;
 +
 +      return 0;
 +}
 +
 +/*
 + * Exchange file1 and file2 contents if file2 has not been written since the
 + * start commit operation.
 + */
 +long
 +xfs_ioc_commit_range(
 +      struct file                     *file,
 +      struct xfs_commit_range __user  *argp)
 +{
 +      struct xfs_exchrange            fxr = {
 +              .file2                  = file,
 +      };
 +      struct xfs_commit_range         args;
 +      struct xfs_commit_range_fresh   *kern_f;
 +      struct xfs_inode                *ip2 = XFS_I(file_inode(file));
 +      struct xfs_mount                *mp = ip2->i_mount;
 +      struct fd                       file1;
 +      int                             error;
 +
 +      kern_f = (struct xfs_commit_range_fresh *)&args.file2_freshness;
 +
 +      if (copy_from_user(&args, argp, sizeof(args)))
 +              return -EFAULT;
 +      if (args.flags & ~XFS_EXCHANGE_RANGE_ALL_FLAGS)
 +              return -EINVAL;
 +      if (kern_f->magic != XCR_FRESH_MAGIC)
 +              return -EBUSY;
 +      if (memcmp(&kern_f->fsid, mp->m_fixedfsid, sizeof(xfs_fsid_t)))
 +              return -EBUSY;
 +
 +      fxr.file1_offset        = args.file1_offset;
 +      fxr.file2_offset        = args.file2_offset;
 +      fxr.length              = args.length;
 +      fxr.flags               = args.flags | __XFS_EXCHANGE_RANGE_CHECK_FRESH2;
 +      fxr.file2_ino           = kern_f->file2_ino;
 +      fxr.file2_gen           = kern_f->file2_gen;
 +      fxr.file2_mtime.tv_sec  = kern_f->file2_mtime;
 +      fxr.file2_mtime.tv_nsec = kern_f->file2_mtime_nsec;
 +      fxr.file2_ctime.tv_sec  = kern_f->file2_ctime;
 +      fxr.file2_ctime.tv_nsec = kern_f->file2_ctime_nsec;
 +
 +      file1 = fdget(args.file1_fd);
-       fxr.file1 = file1.file;
++      if (fd_empty(file1))
 +              return -EBADF;
++      fxr.file1 = fd_file(file1);
 +
 +      error = xfs_exchange_range(&fxr);
 +      fdput(file1);
 +      return error;
 +}
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc kernel/signal.c
Simple merge
diff --cc kernel/sys.c
Simple merge
diff --cc mm/filemap.c
Simple merge
Simple merge
diff --cc mm/readahead.c
Simple merge
Simple merge
diff --cc net/socket.c
Simple merge
Simple merge
Simple merge
Simple merge