Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ef9c292 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents e4ef108f 3d62c45b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -730,14 +730,14 @@ static int __init fcntl_init(void)
	 * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
	 * 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_CREAT		| O_EXCL	| O_NOCTTY	|
		O_TRUNC		| O_APPEND	| /* O_NONBLOCK	| */
		__O_SYNC	| O_DSYNC	| FASYNC	|
		O_DIRECT	| O_LARGEFILE	| O_DIRECTORY	|
		O_NOFOLLOW	| O_NOATIME	| O_CLOEXEC	|
		__FMODE_EXEC	| O_PATH
		__FMODE_EXEC	| O_PATH	| __O_TMPFILE
		));

	fasync_cache = kmem_cache_create("fasync_cache",
+3 −7
Original line number Diff line number Diff line
@@ -3671,15 +3671,11 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
	if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
		return -EINVAL;
	/*
	 * To use null names we require CAP_DAC_READ_SEARCH
	 * This ensures that not everyone will be able to create
	 * handlink using the passed filedescriptor.
	 * Using empty names is equivalent to using AT_SYMLINK_FOLLOW
	 * on /proc/self/fd/<fd>.
	 */
	if (flags & AT_EMPTY_PATH) {
		if (!capable(CAP_DAC_READ_SEARCH))
			return -ENOENT;
	if (flags & AT_EMPTY_PATH)
		how = LOOKUP_EMPTY;
	}

	if (flags & AT_SYMLINK_FOLLOW)
		how |= LOOKUP_FOLLOW;
+1 −1
Original line number Diff line number Diff line
@@ -823,7 +823,7 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
	int lookup_flags = 0;
	int acc_mode;

	if (flags & O_CREAT)
	if (flags & (O_CREAT | __O_TMPFILE))
		op->mode = (mode & S_IALLUGO) | S_IFREG;
	else
		op->mode = 0;
+19 −80
Original line number Diff line number Diff line
@@ -19,12 +19,13 @@
/*
 * 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;

	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 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);

	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;
}

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);
	int level;

@@ -186,8 +189,9 @@ static int show_per_level(struct seq_file *m, struct super_block *sb)
	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);

	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;
}

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_super_block *rs = sb_info->s_rs;
	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;
}

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_super_block *rs = sb_info->s_rs;
	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;
}

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_super_block *rs = r->s_rs;
	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;
}

/* 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)
{
	struct reiserfs_seq_private *priv;
	int ret = seq_open_private(file, &r_ops,
				   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;
	return single_open(file, PDE_DATA(inode), 
				proc_get_parent_data(inode));
}

static const struct file_operations r_file_operations = {
	.open = r_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = seq_release_private,
	.owner = THIS_MODULE,
	.release = single_release,
};

static struct proc_dir_entry *proc_info_root = NULL;
static const char proc_info_root_name[] = "fs/reiserfs";

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,
			 &r_file_operations, func);
+1 −2
Original line number Diff line number Diff line
@@ -499,6 +499,7 @@ int remove_save_link(struct inode *inode, int truncate)
static void reiserfs_kill_sb(struct super_block *s)
{
	if (REISERFS_SB(s)) {
		reiserfs_proc_info_done(s);
		/*
		 * Force any pending inode evictions to occur now. Any
		 * 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_proc_info_done(s);

	reiserfs_write_unlock(s);
	mutex_destroy(&REISERFS_SB(s)->lock);
	kfree(s->s_fs_info);