mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-16 18:26:42 +00:00
9020d0d844
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCZuQEmwAKCRCRxhvAZXjc otRsAQCUdlBS/ky2JiYn3ePURKYVBgRq/+PnmhRrBNDuv+ToZwD+NRLNlOM8FzQy c8BMSq0rkwO2C5Aax3kGxgTPMEuuCwc= =QLvm -----END PGP SIGNATURE----- Merge tag 'vfs-6.12.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs mount updates from Christian Brauner: "Recently, we added the ability to list mounts in other mount namespaces and the ability to retrieve namespace file descriptors without having to go through procfs by deriving them from pidfds. This extends nsfs in two ways: (1) Add the ability to retrieve information about a mount namespace via NS_MNT_GET_INFO. This will return the mount namespace id and the number of mounts currently in the mount namespace. The number of mounts can be used to size the buffer that needs to be used for listmount() and is in general useful without having to actually iterate through all the mounts. The structure is extensible. (2) Add the ability to iterate through all mount namespaces over which the caller holds privilege returning the file descriptor for the next or previous mount namespace. To retrieve a mount namespace the caller must be privileged wrt to it's owning user namespace. This means that PID 1 on the host can list all mounts in all mount namespaces or that a container can list all mounts of its nested containers. Optionally pass a structure for NS_MNT_GET_INFO with NS_MNT_GET_{PREV,NEXT} to retrieve information about the mount namespace in one go. (1) and (2) can be implemented for other namespace types easily. Together with recent api additions this means one can iterate through all mounts in all mount namespaces without ever touching procfs. The commit message in 49224a345c48 ('Merge patch series "nsfs: iterate through mount namespaces"') contains example code how to do this" * tag 'vfs-6.12.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: nsfs: iterate through mount namespaces file: add fput() cleanup helper fs: add put_mnt_ns() cleanup helper fs: allow mount namespace fd
134 lines
3.5 KiB
C
134 lines
3.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Wrapper functions for accessing the file_struct fd array.
|
|
*/
|
|
|
|
#ifndef __LINUX_FILE_H
|
|
#define __LINUX_FILE_H
|
|
|
|
#include <linux/compiler.h>
|
|
#include <linux/types.h>
|
|
#include <linux/posix_types.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/cleanup.h>
|
|
#include <linux/err.h>
|
|
|
|
struct file;
|
|
|
|
extern void fput(struct file *);
|
|
|
|
struct file_operations;
|
|
struct task_struct;
|
|
struct vfsmount;
|
|
struct dentry;
|
|
struct inode;
|
|
struct path;
|
|
extern struct file *alloc_file_pseudo(struct inode *, struct vfsmount *,
|
|
const char *, int flags, const struct file_operations *);
|
|
extern struct file *alloc_file_pseudo_noaccount(struct inode *, struct vfsmount *,
|
|
const char *, int flags, const struct file_operations *);
|
|
extern struct file *alloc_file_clone(struct file *, int flags,
|
|
const struct file_operations *);
|
|
|
|
static inline void fput_light(struct file *file, int fput_needed)
|
|
{
|
|
if (fput_needed)
|
|
fput(file);
|
|
}
|
|
|
|
struct fd {
|
|
struct file *file;
|
|
unsigned int flags;
|
|
};
|
|
#define FDPUT_FPUT 1
|
|
#define FDPUT_POS_UNLOCK 2
|
|
|
|
static inline void fdput(struct fd fd)
|
|
{
|
|
if (fd.flags & FDPUT_FPUT)
|
|
fput(fd.file);
|
|
}
|
|
|
|
extern struct file *fget(unsigned int fd);
|
|
extern struct file *fget_raw(unsigned int fd);
|
|
extern struct file *fget_task(struct task_struct *task, unsigned int fd);
|
|
extern unsigned long __fdget(unsigned int fd);
|
|
extern unsigned long __fdget_raw(unsigned int fd);
|
|
extern unsigned long __fdget_pos(unsigned int fd);
|
|
extern void __f_unlock_pos(struct file *);
|
|
|
|
static inline struct fd __to_fd(unsigned long v)
|
|
{
|
|
return (struct fd){(struct file *)(v & ~3),v & 3};
|
|
}
|
|
|
|
static inline struct fd fdget(unsigned int fd)
|
|
{
|
|
return __to_fd(__fdget(fd));
|
|
}
|
|
|
|
static inline struct fd fdget_raw(unsigned int fd)
|
|
{
|
|
return __to_fd(__fdget_raw(fd));
|
|
}
|
|
|
|
static inline struct fd fdget_pos(int fd)
|
|
{
|
|
return __to_fd(__fdget_pos(fd));
|
|
}
|
|
|
|
static inline void fdput_pos(struct fd f)
|
|
{
|
|
if (f.flags & FDPUT_POS_UNLOCK)
|
|
__f_unlock_pos(f.file);
|
|
fdput(f);
|
|
}
|
|
|
|
DEFINE_CLASS(fd, struct fd, fdput(_T), fdget(fd), int fd)
|
|
DEFINE_CLASS(fd_raw, struct fd, fdput(_T), fdget_raw(fd), int fd)
|
|
|
|
extern int f_dupfd(unsigned int from, struct file *file, unsigned flags);
|
|
extern int replace_fd(unsigned fd, struct file *file, unsigned flags);
|
|
extern void set_close_on_exec(unsigned int fd, int flag);
|
|
extern bool get_close_on_exec(unsigned int fd);
|
|
extern int __get_unused_fd_flags(unsigned flags, unsigned long nofile);
|
|
extern int get_unused_fd_flags(unsigned flags);
|
|
extern void put_unused_fd(unsigned int fd);
|
|
|
|
DEFINE_CLASS(get_unused_fd, int, if (_T >= 0) put_unused_fd(_T),
|
|
get_unused_fd_flags(flags), unsigned flags)
|
|
DEFINE_FREE(fput, struct file *, if (!IS_ERR_OR_NULL(_T)) fput(_T))
|
|
|
|
/*
|
|
* take_fd() will take care to set @fd to -EBADF ensuring that
|
|
* CLASS(get_unused_fd) won't call put_unused_fd(). This makes it
|
|
* easier to rely on CLASS(get_unused_fd):
|
|
*
|
|
* struct file *f;
|
|
*
|
|
* CLASS(get_unused_fd, fd)(O_CLOEXEC);
|
|
* if (fd < 0)
|
|
* return fd;
|
|
*
|
|
* f = dentry_open(&path, O_RDONLY, current_cred());
|
|
* if (IS_ERR(f))
|
|
* return PTR_ERR(f);
|
|
*
|
|
* fd_install(fd, f);
|
|
* return take_fd(fd);
|
|
*/
|
|
#define take_fd(fd) __get_and_null(fd, -EBADF)
|
|
|
|
extern void fd_install(unsigned int fd, struct file *file);
|
|
|
|
int receive_fd(struct file *file, int __user *ufd, unsigned int o_flags);
|
|
|
|
int receive_fd_replace(int new_fd, struct file *file, unsigned int o_flags);
|
|
|
|
extern void flush_delayed_fput(void);
|
|
extern void __fput_sync(struct file *);
|
|
|
|
extern unsigned int sysctl_nr_open_min, sysctl_nr_open_max;
|
|
|
|
#endif /* __LINUX_FILE_H */
|