diff options
| author | Mark Brown <broonie@kernel.org> | 2026-11-13 13:09:58 +0000 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-11-13 13:09:58 +0000 |
| commit | 994dd27406d22abc409df024aa945698aa93f157 (patch) | |
| tree | 0093a89e0e08c4e28eb266eb22b0488bfe49a756 /include/linux | |
| parent | 2d4b3ae1bb5b455194e01645b961e834d3ace6be (diff) | |
| parent | 13419eff849a88a276dec97fa62a532dc7fff400 (diff) | |
| download | linux-next-994dd27406d22abc409df024aa945698aa93f157.tar.gz linux-next-994dd27406d22abc409df024aa945698aa93f157.zip | |
Merge branch 'vfs.all' of https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/backing-dev-defs.h | 23 | ||||
| -rw-r--r-- | include/linux/backing-dev.h | 3 | ||||
| -rw-r--r-- | include/linux/blk_types.h | 1 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 1 | ||||
| -rw-r--r-- | include/linux/cred.h | 20 | ||||
| -rw-r--r-- | include/linux/fcntl.h | 6 | ||||
| -rw-r--r-- | include/linux/file_ref.h | 21 | ||||
| -rw-r--r-- | include/linux/fs.h | 4 | ||||
| -rw-r--r-- | include/linux/fs/super_types.h | 1 | ||||
| -rw-r--r-- | include/linux/fs_struct.h | 3 | ||||
| -rw-r--r-- | include/linux/mm.h | 1 | ||||
| -rw-r--r-- | include/linux/mount.h | 1 | ||||
| -rw-r--r-- | include/linux/proc_fs.h | 5 | ||||
| -rw-r--r-- | include/linux/writeback.h | 1 |
14 files changed, 80 insertions, 11 deletions
diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h index 4f1084937315..7713fd60c985 100644 --- a/include/linux/backing-dev-defs.h +++ b/include/linux/backing-dev-defs.h @@ -100,8 +100,10 @@ struct wb_completion { * refcounted with the number of inodes attached to it, and pins the memcg * and the corresponding blkcg. As the corresponding blkcg for a memcg may * change as blkcg is disabled and enabled higher up in the hierarchy, a wb - * is tested for blkcg after lookup and removed from index on mismatch so - * that a new wb for the combination can be created. + * is tested for blkcg after lookup and killed on mismatch so that a new wb + * for the combination can be created. A killed wb stays in the index until + * it is released or a new wb takes over its slot, so that foreign flushes + * can still reach it. * * Each bdi_writeback that is not embedded into the backing_dev_info must hold * a reference to the parent backing_dev_info. See cgwb_create() for details. @@ -160,6 +162,7 @@ struct bdi_writeback { * to this wb */ struct llist_head switch_wbs_ctxs; /* queued contexts for * writeback switching */ + struct work_struct replaced_work; /* see switch_replaced_cgwb() */ union { struct work_struct release_work; @@ -196,7 +199,7 @@ struct backing_dev_info { struct bdi_writeback wb; /* the root writeback info for this bdi */ struct list_head wb_list; /* list of all wbs */ #ifdef CONFIG_CGROUP_WRITEBACK - struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */ + struct radix_tree_root cgwb_tree; /* radix tree of cgroup wbs, incl. killed */ struct mutex cgwb_release_mutex; /* protect shutdown of wb structs */ struct rw_semaphore wb_switch_rwsem; /* no cgwb switch while syncing */ #endif @@ -230,6 +233,17 @@ static inline bool wb_tryget(struct bdi_writeback *wb) } /** + * wb_tryget_live - try to increment a wb's refcount if it hasn't been killed + * @wb: bdi_writeback to get + */ +static inline bool wb_tryget_live(struct bdi_writeback *wb) +{ + if (wb != &wb->bdi->wb) + return percpu_ref_tryget_live(&wb->refcnt); + return true; +} + +/** * wb_get - increment a wb's refcount * @wb: bdi_writeback to get */ @@ -271,7 +285,8 @@ static inline void wb_put(struct bdi_writeback *wb) * wb_dying - is a wb dying? * @wb: bdi_writeback of interest * - * Returns whether @wb is unlinked and being drained. + * Returns whether @wb has been killed and is being drained. A dying wb may + * still be in bdi->cgwb_tree, see cgwb_kill(). */ static inline bool wb_dying(struct bdi_writeback *wb) { diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index c2284466e7aa..84057fa92f24 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -151,6 +151,7 @@ static inline void bdi_wb_stat_mod(struct inode *inode, enum wb_stat_item item, struct bdi_writeback *wb_get_lookup(struct backing_dev_info *bdi, struct cgroup_subsys_state *memcg_css); +void cgwb_kick_replaced(struct bdi_writeback *wb); struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, struct cgroup_subsys_state *memcg_css, gfp_t gfp); @@ -222,7 +223,7 @@ wb_get_create_current(struct backing_dev_info *bdi, gfp_t gfp) rcu_read_lock(); wb = wb_find_current(bdi); - if (wb && unlikely(!wb_tryget(wb))) + if (wb && unlikely(!wb_tryget_live(wb))) wb = NULL; rcu_read_unlock(); diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 0cc09b975d8f..64287a032120 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -58,6 +58,7 @@ struct block_device { struct address_space *bd_mapping; /* page cache */ atomic_t bd_openers; + unsigned int bd_fs_users; /* Protected by bd_mapping->host->i_rwsem. */ spinlock_t bd_size_lock; /* for bd_inode->i_size updates */ void * bd_claiming; void * bd_holder; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 215753171cef..2d92b2b57079 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1709,6 +1709,7 @@ bool disk_live(struct gendisk *disk); unsigned int block_size(struct block_device *bdev); #ifdef CONFIG_BLOCK +void kill_bdev(struct block_device *bdev); void invalidate_bdev(struct block_device *bdev); int sync_blockdev(struct block_device *bdev); int sync_blockdev_range(struct block_device *bdev, loff_t lstart, loff_t lend); diff --git a/include/linux/cred.h b/include/linux/cred.h index 49c26af37349..7fb1663a5fc6 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -171,6 +171,26 @@ extern int cred_fscmp(const struct cred *, const struct cred *); extern void __init cred_init(void); extern int set_cred_ucounts(struct cred *); +/** + * enum cred_ids - which of its ids a subject acts with + * @CRED_IDS_REAL: uid and gid + * @CRED_IDS_EFFECTIVE: euid and egid + * @CRED_IDS_FS: fsuid and fsgid + */ +enum cred_ids { + CRED_IDS_REAL, + CRED_IDS_EFFECTIVE, + CRED_IDS_FS, +}; + +bool cred_ids_allow_signal(const struct cred *subj, const struct cred *obj); +bool cred_ids_allow_sigio(const struct cred *subj, const struct cred *obj); +bool cred_ids_allow_sched(const struct cred *subj, const struct cred *obj); +bool cred_ids_allow_ioprio(const struct cred *subj, const struct cred *obj); +bool cred_ids_allow_move(const struct cred *subj, const struct cred *obj); +bool cred_ids_allow_control(const struct cred *subj, enum cred_ids which, + const struct cred *obj); + static inline bool cap_ambient_invariant_ok(const struct cred *cred) { return cap_issubset(cred->cap_ambient, diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h index 6ad6b9e7a226..204e16bbe263 100644 --- a/include/linux/fcntl.h +++ b/include/linux/fcntl.h @@ -30,6 +30,12 @@ */ #define __O_REGULAR (1 << 30) +#define O_MKDIR_MASK (O_CREAT | O_DIRECTORY) +static inline bool O_IS_MKDIR(unsigned int flags) +{ + return (flags & O_MKDIR_MASK) == O_MKDIR_MASK; +} + /* List of all valid flags for the how->resolve argument: */ #define VALID_RESOLVE_FLAGS \ (RESOLVE_NO_XDEV | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS | \ diff --git a/include/linux/file_ref.h b/include/linux/file_ref.h index 31551e4cb8f3..e5fc45714fe2 100644 --- a/include/linux/file_ref.h +++ b/include/linux/file_ref.h @@ -69,7 +69,11 @@ bool __file_ref_put(file_ref_t *ref, unsigned long cnt); * * Similar to atomic_inc_not_zero() but saturates at FILE_REF_MAXREF. * - * Provides full memory ordering. + * Provides acquire memory ordering: loads after a successful get are + * ordered after the increment. That is what the pointer recheck of the + * fget-rcu pattern needs, the load of the pointer the reference is + * taken through is ordered before the increment by its address + * dependency. * * Return: False if the attempt to acquire a reference failed. This happens * when the last reference has been put already. True if a reference @@ -78,7 +82,7 @@ bool __file_ref_put(file_ref_t *ref, unsigned long cnt); static __always_inline __must_check bool file_ref_get(file_ref_t *ref) { /* - * Unconditionally increase the reference count with full + * Unconditionally increase the reference count with acquire * ordering. The saturation and dead zones provide enough * tolerance for this. * @@ -105,7 +109,7 @@ static __always_inline __must_check bool file_ref_get(file_ref_t *ref) * FILE_REF_ONEREF. It would need 2305843009213693952/2^61 * file_ref_get()s to resurrect such a dead file. */ - return !atomic_long_add_negative(1, &ref->refcnt); + return !atomic_long_add_negative_acquire(1, &ref->refcnt); } /** @@ -129,6 +133,17 @@ static __always_inline void file_ref_inc(file_ref_t *ref) * are done before, and provides an acquire ordering on success such * that free() must come after. * + * The decrement is fully ordered though and it has to stay that way. + * When the last reference goes synchronously, in __fput_sync() and on + * the fallback path of fput_close_sync(), the full barrier is what + * orders the caller's earlier stores, in close(2) the cleared slot in + * the descriptor table, before the slab handoff that lets another CPU + * reallocate the file. A lookup that increments the recycled counter + * then sees the cleared slot and fails its recheck. The deferred + * fput() has the cmpxchg() of task_work_add() for that, the + * synchronous paths have nothing else. So this is not a candidate for + * atomic_long_dec_return_release(). + * * Return: True if this was the last reference with no future references * possible. This signals the caller that it can safely release * the object which is protected by the reference counter. diff --git a/include/linux/fs.h b/include/linux/fs.h index 5b3a100aba77..58d25fc23ec4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1186,10 +1186,10 @@ static inline unsigned imajor(const struct inode *inode) struct fown_struct { struct file *file; /* backpointer for security modules */ - rwlock_t lock; /* protects pid, uid, euid fields */ + rwlock_t lock; /* protects pid, cred fields */ struct pid *pid; /* pid or -pgrp where SIGIO should be sent */ enum pid_type pid_type; /* Kind of process group SIGIO should be sent to */ - kuid_t uid, euid; /* uid/euid of process setting the owner */ + const struct cred *cred; /* of the process setting the owner */ int signum; /* posix.1b rt signal to be delivered on IO */ }; diff --git a/include/linux/fs/super_types.h b/include/linux/fs/super_types.h index 6ce105fe8359..8176133bcdb3 100644 --- a/include/linux/fs/super_types.h +++ b/include/linux/fs/super_types.h @@ -359,5 +359,6 @@ struct super_block { #define SB_I_NOIDMAP 0x00002000 /* No idmapped mounts on this superblock */ #define SB_I_ALLOW_HSM 0x00004000 /* Allow HSM events on this superblock */ #define SB_I_NO_DATA_INTEGRITY 0x00008000 /* fs cannot guarantee data persistence on sync */ +#define SB_I_NO_ATOMIC_MKDIR 0x00010000 /* no O_CREAT|O_DIRECTORY on this fs */ #endif /* _LINUX_FS_SUPER_TYPES_H */ diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h index 97eef8d3863d..fb725707754d 100644 --- a/include/linux/fs_struct.h +++ b/include/linux/fs_struct.h @@ -42,6 +42,9 @@ static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd) read_sequnlock_excl(&fs->seq); } +int get_task_root(struct task_struct *task, struct path *root); +int get_task_pwd(struct task_struct *task, struct path *pwd); + struct fs_struct *switch_fs_struct(struct fs_struct *new_fs); extern bool current_chrooted(void); diff --git a/include/linux/mm.h b/include/linux/mm.h index 6af3b7008f1a..9971a6f7e607 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -4402,6 +4402,7 @@ extern int set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); extern int replace_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); extern struct file *get_mm_exe_file(struct mm_struct *mm); extern struct file *get_task_exe_file(struct task_struct *task); +int get_task_exe_path(struct task_struct *task, struct path *exe_path); extern void vm_stat_account(struct mm_struct *, vm_flags_t, long npages); diff --git a/include/linux/mount.h b/include/linux/mount.h index 57860e321cf5..e1ef34b5b09d 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -74,7 +74,6 @@ extern void mnt_drop_write(struct vfsmount *mnt); extern void mnt_drop_write_file(struct file *file); extern void mntput(struct vfsmount *mnt); extern struct vfsmount *mntget(struct vfsmount *mnt); -extern void mnt_make_shortterm(struct vfsmount *mnt); extern struct vfsmount *mnt_clone_internal(const struct path *path); extern bool __mnt_is_readonly(const struct vfsmount *mnt); extern bool mnt_may_suid(struct vfsmount *mnt); diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 47d7deaeed8f..903fc811efd4 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -29,6 +29,7 @@ enum { PROC_ENTRY_proc_compat_ioctl = 1U << 2, PROC_ENTRY_proc_lseek = 1U << 3, + PROC_ENTRY_CANT_MOUNT = 1U << 6, PROC_ENTRY_FORCE_LOOKUP = 1U << 7, }; @@ -87,6 +88,8 @@ extern void proc_flush_pid(struct pid *); extern struct proc_dir_entry *proc_symlink(const char *, struct proc_dir_entry *, const char *); +struct proc_dir_entry *proc_self_symlink(const char *, struct proc_dir_entry *, + const char *); struct proc_dir_entry *_proc_mkdir(const char *, umode_t, struct proc_dir_entry *, void *, bool); extern struct proc_dir_entry *proc_mkdir(const char *, struct proc_dir_entry *); extern struct proc_dir_entry *proc_mkdir_data(const char *, umode_t, @@ -179,6 +182,8 @@ static inline void proc_flush_pid(struct pid *pid) static inline struct proc_dir_entry *proc_symlink(const char *name, struct proc_dir_entry *parent,const char *dest) { return NULL;} +static inline struct proc_dir_entry *proc_self_symlink(const char *name, + struct proc_dir_entry *parent, const char *dest) { return NULL; } static inline struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) {return NULL;} static inline struct proc_dir_entry *proc_create_mount_point(const char *name) { return NULL; } diff --git a/include/linux/writeback.h b/include/linux/writeback.h index b749a9a5a5ee..88e4b5049698 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -209,6 +209,7 @@ int cgroup_writeback_by_id(u64 bdi_id, int memcg_id, enum wb_reason reason, struct wb_completion *done); void cgroup_writeback_umount(struct super_block *sb); bool cleanup_offline_cgwb(struct bdi_writeback *wb); +bool switch_replaced_cgwb(struct bdi_writeback *wb); /** * inode_attach_wb - associate an inode with its wb |
