summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-11-13 15:58:24 +0000
committerMark Brown <broonie@kernel.org>2026-11-13 15:58:24 +0000
commitd174829720b5976fb30bc6e05501ce689ad0fb83 (patch)
tree2a28e521157df0d5502a853c11189b4e93618bea /include/linux
parentd5508fb9e1c8042d92c2c453a44923aff57dbd7e (diff)
parentfc876fca34b0d45ea7d9171d0acb16af6649e683 (diff)
downloadlinux-next-d174829720b5976fb30bc6e05501ce689ad0fb83.tar.gz
linux-next-d174829720b5976fb30bc6e05501ce689ad0fb83.zip
Merge branch 'fs-next' of linux-next
# Conflicts: # mm/filemap.c
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/backing-dev-defs.h23
-rw-r--r--include/linux/backing-dev.h3
-rw-r--r--include/linux/blk_types.h1
-rw-r--r--include/linux/blkdev.h1
-rw-r--r--include/linux/ceph/osd_client.h4
-rw-r--r--include/linux/cred.h20
-rw-r--r--include/linux/exportfs_block.h2
-rw-r--r--include/linux/fcntl.h6
-rw-r--r--include/linux/file_ref.h21
-rw-r--r--include/linux/fs.h4
-rw-r--r--include/linux/fs/super_types.h1
-rw-r--r--include/linux/fs_struct.h3
-rw-r--r--include/linux/fscrypt.h21
-rw-r--r--include/linux/mm.h1
-rw-r--r--include/linux/mount.h1
-rw-r--r--include/linux/nfsacl.h5
-rw-r--r--include/linux/proc_fs.h5
-rw-r--r--include/linux/sunrpc/svc.h3
-rw-r--r--include/linux/sunrpc/svc_rdma.h4
-rw-r--r--include/linux/writeback.h1
20 files changed, 93 insertions, 37 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/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index 50b14a5661c7..7349ca09a227 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -314,9 +314,7 @@ struct ceph_osd_linger_request {
bool is_watch; /* watch or notify */
struct ceph_osd *osd;
- struct ceph_osd_request *reg_req;
- struct ceph_osd_request *ping_req;
- unsigned long ping_sent;
+ struct list_head osd_reqs; /* w/ r_private_item */
unsigned long watch_valid_thru;
struct list_head pending_lworks;
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/exportfs_block.h b/include/linux/exportfs_block.h
index de519b7b599b..21e61fc01245 100644
--- a/include/linux/exportfs_block.h
+++ b/include/linux/exportfs_block.h
@@ -44,6 +44,8 @@ struct exportfs_block_ops {
/*
* Map blocks for direct block access.
* If @write is %true, also allocate the blocks for the range if needed.
+ * The mapping returned must contain @offset. It may start before
+ * @offset and may end before or after @offset + @len.
*/
int (*map_blocks)(struct inode *inode, loff_t offset, u64 len,
struct iomap *iomap, bool write,
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/fscrypt.h b/include/linux/fscrypt.h
index 28f2108e29f3..3a238bebbdf1 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -356,16 +356,6 @@ int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
unsigned int len, unsigned int offs,
u64 lblk_num);
-static inline bool fscrypt_is_bounce_page(struct page *page)
-{
- return page->mapping == NULL;
-}
-
-static inline struct page *fscrypt_pagecache_page(struct page *bounce_page)
-{
- return (struct page *)page_private(bounce_page);
-}
-
static inline bool fscrypt_is_bounce_folio(const struct folio *folio)
{
return folio->mapping == NULL;
@@ -527,17 +517,6 @@ static inline int fscrypt_decrypt_block_inplace(const struct inode *inode,
return -EOPNOTSUPP;
}
-static inline bool fscrypt_is_bounce_page(struct page *page)
-{
- return false;
-}
-
-static inline struct page *fscrypt_pagecache_page(struct page *bounce_page)
-{
- WARN_ON_ONCE(1);
- return ERR_PTR(-EINVAL);
-}
-
static inline bool fscrypt_is_bounce_folio(const struct folio *folio)
{
return false;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index e8b67179fa7b..eecb86f15d84 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -4421,6 +4421,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/nfsacl.h b/include/linux/nfsacl.h
index 8e76a79cdc6a..e4155e69c8dd 100644
--- a/include/linux/nfsacl.h
+++ b/include/linux/nfsacl.h
@@ -26,8 +26,9 @@ static inline unsigned int
nfsacl_size(struct posix_acl *acl_access, struct posix_acl *acl_default)
{
unsigned int w = 16;
- w += max(acl_access ? (int)acl_access->a_count : 3, 4) * 12;
- if (acl_default)
+ if (acl_access && acl_access->a_count >= 3)
+ w += max((int)acl_access->a_count, 4) * 12;
+ if (acl_default && acl_default->a_count >= 3)
w += max((int)acl_default->a_count, 4) * 12;
return w;
}
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/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index cfb5ab17dabd..a47f05fc6a12 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -89,6 +89,8 @@ struct svc_serv {
bool sv_is_pooled; /* is this a pooled service? */
/* Caller registers with rpcbind itself. Set before svc_bind(). */
bool sv_no_rpcbind;
+ /* Service implements RPC-with-TLS; offer STARTTLS to AUTH_TLS probes. */
+ bool sv_tls;
struct svc_pool * sv_pools; /* array of thread pools */
int (*sv_threadfn)(void *data);
@@ -360,6 +362,7 @@ static inline void svc_thread_init_status(struct svc_rqst *rqstp, int err)
struct svc_deferred_req {
u32 prot; /* protocol (UDP or TCP) */
+ bool secure; /* RQ_SECURE of the original request */
struct svc_xprt *xprt;
struct sockaddr_storage addr; /* where reply must go */
size_t addrlen;
diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
index 5ccb13bf906f..60966f92e8c8 100644
--- a/include/linux/sunrpc/svc_rdma.h
+++ b/include/linux/sunrpc/svc_rdma.h
@@ -117,6 +117,8 @@ struct svcxprt_rdma {
struct llist_head sc_recv_ctxts;
struct llist_head sc_send_release_list;
+ struct llist_head sc_send_stranded_ctxts;
+ struct llist_head sc_recv_stranded_ctxts;
atomic_t sc_completion_ids;
};
@@ -262,6 +264,7 @@ extern void svc_rdma_handle_bc_reply(struct svc_rqst *rqstp,
/* svc_rdma_recvfrom.c */
extern void svc_rdma_recv_ctxts_destroy(struct svcxprt_rdma *rdma);
+extern void svc_rdma_recv_ctxts_stranded_release(struct svcxprt_rdma *rdma);
extern bool svc_rdma_post_recvs(struct svcxprt_rdma *rdma);
extern struct svc_rdma_recv_ctxt *
svc_rdma_recv_ctxt_get(struct svcxprt_rdma *rdma);
@@ -300,6 +303,7 @@ extern int svc_rdma_process_read_list(struct svcxprt_rdma *rdma,
/* svc_rdma_sendto.c */
extern void svc_rdma_send_ctxts_destroy(struct svcxprt_rdma *rdma);
extern void svc_rdma_send_ctxts_drain(struct svcxprt_rdma *rdma);
+extern void svc_rdma_send_ctxts_stranded_release(struct svcxprt_rdma *rdma);
extern struct svc_rdma_send_ctxt *
svc_rdma_send_ctxt_get(struct svcxprt_rdma *rdma);
extern void svc_rdma_send_ctxt_put(struct svcxprt_rdma *rdma,
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index c50f404141b0..649ce1be4e08 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