Skip to content

Commit

Permalink
Merge tag 'v6.4/vfs.misc' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/vfs/vfs

Pull misc vfs updates from Christian Brauner:
 "This contains a pile of various smaller fixes. Most of them aren't
  very interesting so this just highlights things worth mentioning:

   - Various filesystems contained the same little helper to convert
     from the mode of a dentry to the DT_* type of that dentry.

     They have now all been switched to rely on the generic
     fs_umode_to_dtype() helper. All custom helpers are removed (Jeff)

   - Fsnotify now reports ACCESS and MODIFY events for splice
     (Chung-Chiang Cheng)

   - After converting timerfd a long time ago to rely on
     wait_event_interruptible_*() apis, convert eventfd as well. This
     removes the complex open-coded wait code (Wen Yang)

   - Simplify sysctl registration for devpts, avoiding the declaration
     of two tables. Instead, just use a prefixed path with
     register_sysctl() (Luis)

   - The setattr_should_drop_sgid() helper is now exported so NFS can
     use it. By switching NFS to this helper an NFS setgid inheritance
     bug is fixed (me)"

* tag 'v6.4/vfs.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  fs: hfsplus: remove WARN_ON() from hfsplus_cat_{read,write}_inode()
  pnode: pass mountpoint directly
  eventfd: use wait_event_interruptible_locked_irq() helper
  splice: report related fsnotify events
  fs: consolidate duplicate dt_type helpers
  nfs: use vfs setgid helper
  Update relatime comments to include equality
  fs/buffer: Remove redundant assignment to err
  fs_context: drop the unused lsm_flags member
  fs/namespace: fnic: Switch to use %ptTd
  Documentation: update idmappings.rst
  devpts: simplify two-level sysctl registration for pty_kern_table
  eventpoll: align comment with nested epoll limitation
  • Loading branch information
Linus Torvalds committed Apr 24, 2023
2 parents 7bcff5a + 81b21c0 commit e2eff52
Show file tree
Hide file tree
Showing 21 changed files with 191 additions and 168 deletions.
178 changes: 125 additions & 53 deletions Documentation/filesystems/idmappings.rst

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Documentation/filesystems/mount_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ context. This is represented by the fs_context structure::
unsigned int sb_flags;
unsigned int sb_flags_mask;
unsigned int s_iflags;
unsigned int lsm_flags;
enum fs_context_purpose purpose:8;
...
};
Expand Down
1 change: 1 addition & 0 deletions fs/attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ int setattr_should_drop_sgid(struct mnt_idmap *idmap,
return ATTR_KILL_SGID;
return 0;
}
EXPORT_SYMBOL(setattr_should_drop_sgid);

/**
* setattr_should_drop_suidgid - determine whether the set{g,u}id bit needs to
Expand Down
9 changes: 3 additions & 6 deletions fs/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2581,7 +2581,7 @@ int block_truncate_page(struct address_space *mapping,
struct inode *inode = mapping->host;
struct page *page;
struct buffer_head *bh;
int err;
int err = 0;

blocksize = i_blocksize(inode);
length = offset & (blocksize - 1);
Expand All @@ -2594,9 +2594,8 @@ int block_truncate_page(struct address_space *mapping,
iblock = (sector_t)index << (PAGE_SHIFT - inode->i_blkbits);

page = grab_cache_page(mapping, index);
err = -ENOMEM;
if (!page)
goto out;
return -ENOMEM;

if (!page_has_buffers(page))
create_empty_buffers(page, blocksize, 0);
Expand All @@ -2610,7 +2609,6 @@ int block_truncate_page(struct address_space *mapping,
pos += blocksize;
}

err = 0;
if (!buffer_mapped(bh)) {
WARN_ON(bh->b_size != blocksize);
err = get_block(inode, iblock, bh, 0);
Expand All @@ -2634,12 +2632,11 @@ int block_truncate_page(struct address_space *mapping,

zero_user(page, offset, length);
mark_buffer_dirty(bh);
err = 0;

unlock:
unlock_page(page);
put_page(page);
out:

return err;
}
EXPORT_SYMBOL(block_truncate_page);
Expand Down
9 changes: 2 additions & 7 deletions fs/configfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1599,12 +1599,6 @@ static int configfs_dir_close(struct inode *inode, struct file *file)
return 0;
}

/* Relationship between s_mode and the DT_xxx types */
static inline unsigned char dt_type(struct configfs_dirent *sd)
{
return (sd->s_mode >> 12) & 15;
}

static int configfs_readdir(struct file *file, struct dir_context *ctx)
{
struct dentry *dentry = file->f_path.dentry;
Expand Down Expand Up @@ -1654,7 +1648,8 @@ static int configfs_readdir(struct file *file, struct dir_context *ctx)
name = configfs_get_name(next);
len = strlen(name);

if (!dir_emit(ctx, name, len, ino, dt_type(next)))
if (!dir_emit(ctx, name, len, ino,
fs_umode_to_dtype(next->s_mode)))
return 0;

spin_lock(&configfs_dirent_lock);
Expand Down
20 changes: 1 addition & 19 deletions fs/devpts/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,24 +72,6 @@ static struct ctl_table pty_table[] = {
{}
};

static struct ctl_table pty_kern_table[] = {
{
.procname = "pty",
.mode = 0555,
.child = pty_table,
},
{}
};

static struct ctl_table pty_root_table[] = {
{
.procname = "kernel",
.mode = 0555,
.child = pty_kern_table,
},
{}
};

struct pts_mount_opts {
int setuid;
int setgid;
Expand Down Expand Up @@ -630,7 +612,7 @@ static int __init init_devpts_fs(void)
{
int err = register_filesystem(&devpts_fs_type);
if (!err) {
register_sysctl_table(pty_root_table);
register_sysctl("kernel/pty", pty_table);
}
return err;
}
Expand Down
41 changes: 7 additions & 34 deletions fs/eventfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to)
struct file *file = iocb->ki_filp;
struct eventfd_ctx *ctx = file->private_data;
__u64 ucnt = 0;
DECLARE_WAITQUEUE(wait, current);

if (iov_iter_count(to) < sizeof(ucnt))
return -EINVAL;
Expand All @@ -239,23 +238,11 @@ static ssize_t eventfd_read(struct kiocb *iocb, struct iov_iter *to)
spin_unlock_irq(&ctx->wqh.lock);
return -EAGAIN;
}
__add_wait_queue(&ctx->wqh, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (ctx->count)
break;
if (signal_pending(current)) {
__remove_wait_queue(&ctx->wqh, &wait);
__set_current_state(TASK_RUNNING);
spin_unlock_irq(&ctx->wqh.lock);
return -ERESTARTSYS;
}

if (wait_event_interruptible_locked_irq(ctx->wqh, ctx->count)) {
spin_unlock_irq(&ctx->wqh.lock);
schedule();
spin_lock_irq(&ctx->wqh.lock);
return -ERESTARTSYS;
}
__remove_wait_queue(&ctx->wqh, &wait);
__set_current_state(TASK_RUNNING);
}
eventfd_ctx_do_read(ctx, &ucnt);
current->in_eventfd = 1;
Expand All @@ -275,7 +262,6 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
struct eventfd_ctx *ctx = file->private_data;
ssize_t res;
__u64 ucnt;
DECLARE_WAITQUEUE(wait, current);

if (count < sizeof(ucnt))
return -EINVAL;
Expand All @@ -288,23 +274,10 @@ static ssize_t eventfd_write(struct file *file, const char __user *buf, size_t c
if (ULLONG_MAX - ctx->count > ucnt)
res = sizeof(ucnt);
else if (!(file->f_flags & O_NONBLOCK)) {
__add_wait_queue(&ctx->wqh, &wait);
for (res = 0;;) {
set_current_state(TASK_INTERRUPTIBLE);
if (ULLONG_MAX - ctx->count > ucnt) {
res = sizeof(ucnt);
break;
}
if (signal_pending(current)) {
res = -ERESTARTSYS;
break;
}
spin_unlock_irq(&ctx->wqh.lock);
schedule();
spin_lock_irq(&ctx->wqh.lock);
}
__remove_wait_queue(&ctx->wqh, &wait);
__set_current_state(TASK_RUNNING);
res = wait_event_interruptible_locked_irq(ctx->wqh,
ULLONG_MAX - ctx->count > ucnt);
if (!res)
res = sizeof(ucnt);
}
if (likely(res > 0)) {
ctx->count += ucnt;
Expand Down
4 changes: 2 additions & 2 deletions fs/eventpoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,8 +483,8 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
* (efd1) notices that it may have some event ready, so it needs to wake up
* the waiters on its poll wait list (efd2). So it calls ep_poll_safewake()
* that ends up in another wake_up(), after having checked about the
* recursion constraints. That are, no more than EP_MAX_POLLWAKE_NESTS, to
* avoid stack blasting.
* recursion constraints. That are, no more than EP_MAX_NESTS, to avoid
* stack blasting.
*
* When CONFIG_DEBUG_LOCK_ALLOC is enabled, make sure lockdep can handle
* this special case of epoll.
Expand Down
28 changes: 23 additions & 5 deletions fs/hfsplus/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
if (type == HFSPLUS_FOLDER) {
struct hfsplus_cat_folder *folder = &entry.folder;

WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_folder));
if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) {
pr_err("bad catalog folder entry\n");
res = -EIO;
goto out;
}
hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
sizeof(struct hfsplus_cat_folder));
hfsplus_get_perms(inode, &folder->permissions, 1);
Expand All @@ -531,7 +535,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
} else if (type == HFSPLUS_FILE) {
struct hfsplus_cat_file *file = &entry.file;

WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_file));
if (fd->entrylength < sizeof(struct hfsplus_cat_file)) {
pr_err("bad catalog file entry\n");
res = -EIO;
goto out;
}
hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
sizeof(struct hfsplus_cat_file));

Expand Down Expand Up @@ -562,6 +570,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
pr_err("bad catalog entry used to create inode\n");
res = -EIO;
}
out:
return res;
}

Expand All @@ -570,6 +579,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
struct inode *main_inode = inode;
struct hfs_find_data fd;
hfsplus_cat_entry entry;
int res = 0;

if (HFSPLUS_IS_RSRC(inode))
main_inode = HFSPLUS_I(inode)->rsrc_inode;
Expand All @@ -588,7 +598,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
if (S_ISDIR(main_inode->i_mode)) {
struct hfsplus_cat_folder *folder = &entry.folder;

WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_folder));
if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) {
pr_err("bad catalog folder entry\n");
res = -EIO;
goto out;
}
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_folder));
/* simple node checks? */
Expand All @@ -613,7 +627,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
} else {
struct hfsplus_cat_file *file = &entry.file;

WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_file));
if (fd.entrylength < sizeof(struct hfsplus_cat_file)) {
pr_err("bad catalog file entry\n");
res = -EIO;
goto out;
}
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_file));
hfsplus_inode_write_fork(inode, &file->data_fork);
Expand All @@ -634,7 +652,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
out:
hfs_find_exit(&fd);
return 0;
return res;
}

int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa)
Expand Down
8 changes: 4 additions & 4 deletions fs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1804,8 +1804,8 @@ EXPORT_SYMBOL(bmap);

/*
* With relative atime, only update atime if the previous atime is
* earlier than either the ctime or mtime or if at least a day has
* passed since the last atime update.
* earlier than or equal to either the ctime or mtime,
* or if at least a day has passed since the last atime update.
*/
static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
struct timespec64 now)
Expand All @@ -1814,12 +1814,12 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
if (!(mnt->mnt_flags & MNT_RELATIME))
return 1;
/*
* Is mtime younger than atime? If yes, update atime:
* Is mtime younger than or equal to atime? If yes, update atime:
*/
if (timespec64_compare(&inode->i_mtime, &inode->i_atime) >= 0)
return 1;
/*
* Is ctime younger than atime? If yes, update atime:
* Is ctime younger than or equal to atime? If yes, update atime:
*/
if (timespec64_compare(&inode->i_ctime, &inode->i_atime) >= 0)
return 1;
Expand Down
2 changes: 0 additions & 2 deletions fs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,6 @@ ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *po
/*
* fs/attr.c
*/
int setattr_should_drop_sgid(struct mnt_idmap *idmap,
const struct inode *inode);
struct mnt_idmap *alloc_mnt_idmap(struct user_namespace *mnt_userns);
struct mnt_idmap *mnt_idmap_get(struct mnt_idmap *idmap);
void mnt_idmap_put(struct mnt_idmap *idmap);
8 changes: 1 addition & 7 deletions fs/kernfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1748,12 +1748,6 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
return error;
}

/* Relationship between mode and the DT_xxx types */
static inline unsigned char dt_type(struct kernfs_node *kn)
{
return (kn->mode >> 12) & 15;
}

static int kernfs_dir_fop_release(struct inode *inode, struct file *filp)
{
kernfs_put(filp->private_data);
Expand Down Expand Up @@ -1831,7 +1825,7 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx)
pos;
pos = kernfs_dir_next_pos(ns, parent, ctx->pos, pos)) {
const char *name = pos->name;
unsigned int type = dt_type(pos);
unsigned int type = fs_umode_to_dtype(pos->mode);
int len = strlen(name);
ino_t ino = kernfs_ino(pos);

Expand Down
9 changes: 2 additions & 7 deletions fs/libfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,6 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence)
}
EXPORT_SYMBOL(dcache_dir_lseek);

/* Relationship between i_mode and the DT_xxx types */
static inline unsigned char dt_type(struct inode *inode)
{
return (inode->i_mode >> 12) & 15;
}

/*
* Directory is locked and all positive dentries in it are safe, since
* for ramfs-type trees they can't go away without unlink() or rmdir(),
Expand All @@ -206,7 +200,8 @@ int dcache_readdir(struct file *file, struct dir_context *ctx)

while ((next = scan_positives(cursor, p, 1, next)) != NULL) {
if (!dir_emit(ctx, next->d_name.name, next->d_name.len,
d_inode(next)->i_ino, dt_type(d_inode(next))))
d_inode(next)->i_ino,
fs_umode_to_dtype(d_inode(next)->i_mode)))
break;
ctx->pos++;
p = &next->d_child;
Expand Down
9 changes: 3 additions & 6 deletions fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2617,15 +2617,12 @@ static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *
(ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) {
char *buf = (char *)__get_free_page(GFP_KERNEL);
char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM);
struct tm tm;

time64_to_tm(sb->s_time_max, 0, &tm);

pr_warn("%s filesystem being %s at %s supports timestamps until %04ld (0x%llx)\n",
pr_warn("%s filesystem being %s at %s supports timestamps until %ptTd (0x%llx)\n",
sb->s_type->name,
is_mounted(mnt) ? "remounted" : "mounted",
mntpath,
tm.tm_year+1900, (unsigned long long)sb->s_time_max);
mntpath, &sb->s_time_max,
(unsigned long long)sb->s_time_max);

free_page((unsigned long)buf);
sb->s_iflags |= SB_I_TS_EXPIRY_WARNED;
Expand Down
4 changes: 1 addition & 3 deletions fs/nfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -717,9 +717,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr,
if ((attr->ia_valid & ATTR_KILL_SUID) != 0 &&
inode->i_mode & S_ISUID)
inode->i_mode &= ~S_ISUID;
if ((attr->ia_valid & ATTR_KILL_SGID) != 0 &&
(inode->i_mode & (S_ISGID | S_IXGRP)) ==
(S_ISGID | S_IXGRP))
if (setattr_should_drop_sgid(&nop_mnt_idmap, inode))
inode->i_mode &= ~S_ISGID;
if ((attr->ia_valid & ATTR_MODE) != 0) {
int mode = attr->ia_mode & S_IALLUGO;
Expand Down
3 changes: 0 additions & 3 deletions fs/nfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1274,9 +1274,6 @@ int nfs_get_tree_common(struct fs_context *fc)
if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS)
fc->sb_flags |= SB_SYNCHRONOUS;

if (server->caps & NFS_CAP_SECURITY_LABEL)
fc->lsm_flags |= SECURITY_LSM_NATIVE_LABELS;

/* Get a superblock - note that we may end up sharing one that already exists */
fc->s_fs_info = server;
s = sget_fc(fc, compare_super, nfs_set_super);
Expand Down
Loading

0 comments on commit e2eff52

Please sign in to comment.