mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-03-20 19:11:02 +07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: vfs: add missing check for __O_TMPFILE in fcntl_init() fs: Allow unprivileged linkat(..., AT_EMPTY_PATH) aka flink fs: Fix file mode for O_TMPFILE reiserfs: fix deadlock in umount
This commit is contained in:
commit
8ef9c292ac
@ -730,14 +730,14 @@ static int __init fcntl_init(void)
|
|||||||
* Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
|
* Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
|
||||||
* is defined as O_NONBLOCK on some platforms and not on others.
|
* is defined as O_NONBLOCK on some platforms and not on others.
|
||||||
*/
|
*/
|
||||||
BUILD_BUG_ON(19 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
|
BUILD_BUG_ON(20 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
|
||||||
O_RDONLY | O_WRONLY | O_RDWR |
|
O_RDONLY | O_WRONLY | O_RDWR |
|
||||||
O_CREAT | O_EXCL | O_NOCTTY |
|
O_CREAT | O_EXCL | O_NOCTTY |
|
||||||
O_TRUNC | O_APPEND | /* O_NONBLOCK | */
|
O_TRUNC | O_APPEND | /* O_NONBLOCK | */
|
||||||
__O_SYNC | O_DSYNC | FASYNC |
|
__O_SYNC | O_DSYNC | FASYNC |
|
||||||
O_DIRECT | O_LARGEFILE | O_DIRECTORY |
|
O_DIRECT | O_LARGEFILE | O_DIRECTORY |
|
||||||
O_NOFOLLOW | O_NOATIME | O_CLOEXEC |
|
O_NOFOLLOW | O_NOATIME | O_CLOEXEC |
|
||||||
__FMODE_EXEC | O_PATH
|
__FMODE_EXEC | O_PATH | __O_TMPFILE
|
||||||
));
|
));
|
||||||
|
|
||||||
fasync_cache = kmem_cache_create("fasync_cache",
|
fasync_cache = kmem_cache_create("fasync_cache",
|
||||||
|
10
fs/namei.c
10
fs/namei.c
@ -3671,15 +3671,11 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
|
|||||||
if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
|
if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
/*
|
/*
|
||||||
* To use null names we require CAP_DAC_READ_SEARCH
|
* Using empty names is equivalent to using AT_SYMLINK_FOLLOW
|
||||||
* This ensures that not everyone will be able to create
|
* on /proc/self/fd/<fd>.
|
||||||
* handlink using the passed filedescriptor.
|
|
||||||
*/
|
*/
|
||||||
if (flags & AT_EMPTY_PATH) {
|
if (flags & AT_EMPTY_PATH)
|
||||||
if (!capable(CAP_DAC_READ_SEARCH))
|
|
||||||
return -ENOENT;
|
|
||||||
how = LOOKUP_EMPTY;
|
how = LOOKUP_EMPTY;
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & AT_SYMLINK_FOLLOW)
|
if (flags & AT_SYMLINK_FOLLOW)
|
||||||
how |= LOOKUP_FOLLOW;
|
how |= LOOKUP_FOLLOW;
|
||||||
|
@ -823,7 +823,7 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
|
|||||||
int lookup_flags = 0;
|
int lookup_flags = 0;
|
||||||
int acc_mode;
|
int acc_mode;
|
||||||
|
|
||||||
if (flags & O_CREAT)
|
if (flags & (O_CREAT | __O_TMPFILE))
|
||||||
op->mode = (mode & S_IALLUGO) | S_IFREG;
|
op->mode = (mode & S_IALLUGO) | S_IFREG;
|
||||||
else
|
else
|
||||||
op->mode = 0;
|
op->mode = 0;
|
||||||
|
@ -19,12 +19,13 @@
|
|||||||
/*
|
/*
|
||||||
* LOCKING:
|
* LOCKING:
|
||||||
*
|
*
|
||||||
* We rely on new Alexander Viro's super-block locking.
|
* These guys are evicted from procfs as the very first step in ->kill_sb().
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int show_version(struct seq_file *m, struct super_block *sb)
|
static int show_version(struct seq_file *m, void *unused)
|
||||||
{
|
{
|
||||||
|
struct super_block *sb = m->private;
|
||||||
char *format;
|
char *format;
|
||||||
|
|
||||||
if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) {
|
if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) {
|
||||||
@ -66,8 +67,9 @@ static int show_version(struct seq_file *m, struct super_block *sb)
|
|||||||
#define DJP( x ) le32_to_cpu( jp -> x )
|
#define DJP( x ) le32_to_cpu( jp -> x )
|
||||||
#define JF( x ) ( r -> s_journal -> x )
|
#define JF( x ) ( r -> s_journal -> x )
|
||||||
|
|
||||||
static int show_super(struct seq_file *m, struct super_block *sb)
|
static int show_super(struct seq_file *m, void *unused)
|
||||||
{
|
{
|
||||||
|
struct super_block *sb = m->private;
|
||||||
struct reiserfs_sb_info *r = REISERFS_SB(sb);
|
struct reiserfs_sb_info *r = REISERFS_SB(sb);
|
||||||
|
|
||||||
seq_printf(m, "state: \t%s\n"
|
seq_printf(m, "state: \t%s\n"
|
||||||
@ -128,8 +130,9 @@ static int show_super(struct seq_file *m, struct super_block *sb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show_per_level(struct seq_file *m, struct super_block *sb)
|
static int show_per_level(struct seq_file *m, void *unused)
|
||||||
{
|
{
|
||||||
|
struct super_block *sb = m->private;
|
||||||
struct reiserfs_sb_info *r = REISERFS_SB(sb);
|
struct reiserfs_sb_info *r = REISERFS_SB(sb);
|
||||||
int level;
|
int level;
|
||||||
|
|
||||||
@ -186,8 +189,9 @@ static int show_per_level(struct seq_file *m, struct super_block *sb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show_bitmap(struct seq_file *m, struct super_block *sb)
|
static int show_bitmap(struct seq_file *m, void *unused)
|
||||||
{
|
{
|
||||||
|
struct super_block *sb = m->private;
|
||||||
struct reiserfs_sb_info *r = REISERFS_SB(sb);
|
struct reiserfs_sb_info *r = REISERFS_SB(sb);
|
||||||
|
|
||||||
seq_printf(m, "free_block: %lu\n"
|
seq_printf(m, "free_block: %lu\n"
|
||||||
@ -218,8 +222,9 @@ static int show_bitmap(struct seq_file *m, struct super_block *sb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show_on_disk_super(struct seq_file *m, struct super_block *sb)
|
static int show_on_disk_super(struct seq_file *m, void *unused)
|
||||||
{
|
{
|
||||||
|
struct super_block *sb = m->private;
|
||||||
struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
|
struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
|
||||||
struct reiserfs_super_block *rs = sb_info->s_rs;
|
struct reiserfs_super_block *rs = sb_info->s_rs;
|
||||||
int hash_code = DFL(s_hash_function_code);
|
int hash_code = DFL(s_hash_function_code);
|
||||||
@ -261,8 +266,9 @@ static int show_on_disk_super(struct seq_file *m, struct super_block *sb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show_oidmap(struct seq_file *m, struct super_block *sb)
|
static int show_oidmap(struct seq_file *m, void *unused)
|
||||||
{
|
{
|
||||||
|
struct super_block *sb = m->private;
|
||||||
struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
|
struct reiserfs_sb_info *sb_info = REISERFS_SB(sb);
|
||||||
struct reiserfs_super_block *rs = sb_info->s_rs;
|
struct reiserfs_super_block *rs = sb_info->s_rs;
|
||||||
unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize);
|
unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize);
|
||||||
@ -291,8 +297,9 @@ static int show_oidmap(struct seq_file *m, struct super_block *sb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show_journal(struct seq_file *m, struct super_block *sb)
|
static int show_journal(struct seq_file *m, void *unused)
|
||||||
{
|
{
|
||||||
|
struct super_block *sb = m->private;
|
||||||
struct reiserfs_sb_info *r = REISERFS_SB(sb);
|
struct reiserfs_sb_info *r = REISERFS_SB(sb);
|
||||||
struct reiserfs_super_block *rs = r->s_rs;
|
struct reiserfs_super_block *rs = r->s_rs;
|
||||||
struct journal_params *jp = &rs->s_v1.s_journal;
|
struct journal_params *jp = &rs->s_v1.s_journal;
|
||||||
@ -383,92 +390,24 @@ static int show_journal(struct seq_file *m, struct super_block *sb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iterator */
|
|
||||||
static int test_sb(struct super_block *sb, void *data)
|
|
||||||
{
|
|
||||||
return data == sb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_sb(struct super_block *sb, void *data)
|
|
||||||
{
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct reiserfs_seq_private {
|
|
||||||
struct super_block *sb;
|
|
||||||
int (*show) (struct seq_file *, struct super_block *);
|
|
||||||
};
|
|
||||||
|
|
||||||
static void *r_start(struct seq_file *m, loff_t * pos)
|
|
||||||
{
|
|
||||||
struct reiserfs_seq_private *priv = m->private;
|
|
||||||
loff_t l = *pos;
|
|
||||||
|
|
||||||
if (l)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, priv->sb)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
up_write(&priv->sb->s_umount);
|
|
||||||
return priv->sb;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *r_next(struct seq_file *m, void *v, loff_t * pos)
|
|
||||||
{
|
|
||||||
++*pos;
|
|
||||||
if (v)
|
|
||||||
deactivate_super(v);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void r_stop(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
if (v)
|
|
||||||
deactivate_super(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r_show(struct seq_file *m, void *v)
|
|
||||||
{
|
|
||||||
struct reiserfs_seq_private *priv = m->private;
|
|
||||||
return priv->show(m, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct seq_operations r_ops = {
|
|
||||||
.start = r_start,
|
|
||||||
.next = r_next,
|
|
||||||
.stop = r_stop,
|
|
||||||
.show = r_show,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int r_open(struct inode *inode, struct file *file)
|
static int r_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct reiserfs_seq_private *priv;
|
return single_open(file, PDE_DATA(inode),
|
||||||
int ret = seq_open_private(file, &r_ops,
|
proc_get_parent_data(inode));
|
||||||
sizeof(struct reiserfs_seq_private));
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
struct seq_file *m = file->private_data;
|
|
||||||
priv = m->private;
|
|
||||||
priv->sb = proc_get_parent_data(inode);
|
|
||||||
priv->show = PDE_DATA(inode);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations r_file_operations = {
|
static const struct file_operations r_file_operations = {
|
||||||
.open = r_open,
|
.open = r_open,
|
||||||
.read = seq_read,
|
.read = seq_read,
|
||||||
.llseek = seq_lseek,
|
.llseek = seq_lseek,
|
||||||
.release = seq_release_private,
|
.release = single_release,
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct proc_dir_entry *proc_info_root = NULL;
|
static struct proc_dir_entry *proc_info_root = NULL;
|
||||||
static const char proc_info_root_name[] = "fs/reiserfs";
|
static const char proc_info_root_name[] = "fs/reiserfs";
|
||||||
|
|
||||||
static void add_file(struct super_block *sb, char *name,
|
static void add_file(struct super_block *sb, char *name,
|
||||||
int (*func) (struct seq_file *, struct super_block *))
|
int (*func) (struct seq_file *, void *))
|
||||||
{
|
{
|
||||||
proc_create_data(name, 0, REISERFS_SB(sb)->procdir,
|
proc_create_data(name, 0, REISERFS_SB(sb)->procdir,
|
||||||
&r_file_operations, func);
|
&r_file_operations, func);
|
||||||
|
@ -499,6 +499,7 @@ int remove_save_link(struct inode *inode, int truncate)
|
|||||||
static void reiserfs_kill_sb(struct super_block *s)
|
static void reiserfs_kill_sb(struct super_block *s)
|
||||||
{
|
{
|
||||||
if (REISERFS_SB(s)) {
|
if (REISERFS_SB(s)) {
|
||||||
|
reiserfs_proc_info_done(s);
|
||||||
/*
|
/*
|
||||||
* Force any pending inode evictions to occur now. Any
|
* Force any pending inode evictions to occur now. Any
|
||||||
* inodes to be removed that have extended attributes
|
* inodes to be removed that have extended attributes
|
||||||
@ -554,8 +555,6 @@ static void reiserfs_put_super(struct super_block *s)
|
|||||||
REISERFS_SB(s)->reserved_blocks);
|
REISERFS_SB(s)->reserved_blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
reiserfs_proc_info_done(s);
|
|
||||||
|
|
||||||
reiserfs_write_unlock(s);
|
reiserfs_write_unlock(s);
|
||||||
mutex_destroy(&REISERFS_SB(s)->lock);
|
mutex_destroy(&REISERFS_SB(s)->lock);
|
||||||
kfree(s->s_fs_info);
|
kfree(s->s_fs_info);
|
||||||
|
Loading…
Reference in New Issue
Block a user