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

Commit 5cd9599b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  autofs4: deal with autofs4_write/autofs4_write races
  autofs4: catatonic_mode vs. notify_daemon race
  autofs4: autofs4_wait() vs. autofs4_catatonic_mode() race
  hfsplus: creation of hidden dir on mount can fail
  block_dev: Suppress bdev_cache_init() kmemleak warninig
  fix shrink_dcache_parent() livelock
  coda: switch coda_cnode_make() to sane API as well, clean coda_lookup()
  coda: deal correctly with allocation failure from coda_cnode_makectl()
  securityfs: fix object creation races
parents e343a895 d668dc56
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ struct autofs_sb_info {
	int needs_reghost;
	struct super_block *sb;
	struct mutex wq_mutex;
	struct mutex pipe_mutex;
	spinlock_t fs_lock;
	struct autofs_wait_queue *queues; /* Wait queue pointer */
	spinlock_t lookup_lock;
+1 −0
Original line number Diff line number Diff line
@@ -225,6 +225,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
	sbi->min_proto = 0;
	sbi->max_proto = 0;
	mutex_init(&sbi->wq_mutex);
	mutex_init(&sbi->pipe_mutex);
	spin_lock_init(&sbi->fs_lock);
	sbi->queues = NULL;
	spin_lock_init(&sbi->lookup_lock);
+25 −15
Original line number Diff line number Diff line
@@ -56,26 +56,27 @@ void autofs4_catatonic_mode(struct autofs_sb_info *sbi)
	mutex_unlock(&sbi->wq_mutex);
}

static int autofs4_write(struct file *file, const void *addr, int bytes)
static int autofs4_write(struct autofs_sb_info *sbi,
			 struct file *file, const void *addr, int bytes)
{
	unsigned long sigpipe, flags;
	mm_segment_t fs;
	const char *data = (const char *)addr;
	ssize_t wr = 0;

	/** WARNING: this is not safe for writing more than PIPE_BUF bytes! **/

	sigpipe = sigismember(&current->pending.signal, SIGPIPE);

	/* Save pointer to user space and point back to kernel space */
	fs = get_fs();
	set_fs(KERNEL_DS);

	mutex_lock(&sbi->pipe_mutex);
	while (bytes &&
	       (wr = file->f_op->write(file,data,bytes,&file->f_pos)) > 0) {
		data += wr;
		bytes -= wr;
	}
	mutex_lock(&sbi->pipe_mutex);

	set_fs(fs);

@@ -110,6 +111,13 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,

	pkt.hdr.proto_version = sbi->version;
	pkt.hdr.type = type;
	mutex_lock(&sbi->wq_mutex);

	/* Check if we have become catatonic */
	if (sbi->catatonic) {
		mutex_unlock(&sbi->wq_mutex);
		return;
	}
	switch (type) {
	/* Kernel protocol v4 missing and expire packets */
	case autofs_ptype_missing:
@@ -163,23 +171,19 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
	}
	default:
		printk("autofs4_notify_daemon: bad type %d!\n", type);
		mutex_unlock(&sbi->wq_mutex);
		return;
	}

	/* Check if we have become catatonic */
	mutex_lock(&sbi->wq_mutex);
	if (!sbi->catatonic) {
	pipe = sbi->pipe;
	get_file(pipe);
	}

	mutex_unlock(&sbi->wq_mutex);

	if (pipe) {
		if (autofs4_write(pipe, &pkt, pktsz))
	if (autofs4_write(sbi, pipe, &pkt, pktsz))
		autofs4_catatonic_mode(sbi);
	fput(pipe);
}
}

static int autofs4_getpath(struct autofs_sb_info *sbi,
			   struct dentry *dentry, char **name)
@@ -257,6 +261,9 @@ static int validate_request(struct autofs_wait_queue **wait,
	struct autofs_wait_queue *wq;
	struct autofs_info *ino;

	if (sbi->catatonic)
		return -ENOENT;

	/* Wait in progress, continue; */
	wq = autofs4_find_wait(sbi, qstr);
	if (wq) {
@@ -289,6 +296,9 @@ static int validate_request(struct autofs_wait_queue **wait,
			if (mutex_lock_interruptible(&sbi->wq_mutex))
				return -EINTR;

			if (sbi->catatonic)
				return -ENOENT;

			wq = autofs4_find_wait(sbi, qstr);
			if (wq) {
				*wait = wq;
@@ -389,7 +399,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,

	ret = validate_request(&wq, sbi, &qstr, dentry, notify);
	if (ret <= 0) {
		if (ret == 0)
		if (ret != -EINTR)
			mutex_unlock(&sbi->wq_mutex);
		kfree(qstr.name);
		return ret;
+2 −8
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@
#include <linux/uio.h>
#include <linux/namei.h>
#include <linux/log2.h>
#include <linux/kmemleak.h>
#include <linux/cleancache.h>
#include <asm/uaccess.h>
#include "internal.h"
@@ -521,7 +520,7 @@ static struct super_block *blockdev_superblock __read_mostly;
void __init bdev_cache_init(void)
{
	int err;
	struct vfsmount *bd_mnt;
	static struct vfsmount *bd_mnt;

	bdev_cachep = kmem_cache_create("bdev_cache", sizeof(struct bdev_inode),
			0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
@@ -533,11 +532,6 @@ void __init bdev_cache_init(void)
	bd_mnt = kern_mount(&bd_type);
	if (IS_ERR(bd_mnt))
		panic("Cannot create bdev pseudo-fs");
	/*
	 * This vfsmount structure is only used to obtain the
	 * blockdev_superblock, so tell kmemleak not to report it.
	 */
	kmemleak_not_leak(bd_mnt);
	blockdev_superblock = bd_mnt->mnt_sb;   /* For writeback */
}

+16 −22
Original line number Diff line number Diff line
@@ -88,24 +88,21 @@ struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid,
   - link the two up if this is needed
   - fill in the attributes
*/
int coda_cnode_make(struct inode **inode, struct CodaFid *fid, struct super_block *sb)
struct inode *coda_cnode_make(struct CodaFid *fid, struct super_block *sb)
{
        struct coda_vattr attr;
	struct inode *inode;
        int error;
        
	/* We get inode numbers from Venus -- see venus source */
	error = venus_getattr(sb, fid, &attr);
	if ( error ) {
	    *inode = NULL;
	    return error;
	} 
	if (error)
		return ERR_PTR(error);

	*inode = coda_iget(sb, fid, &attr);
	if ( IS_ERR(*inode) ) {
	inode = coda_iget(sb, fid, &attr);
	if (IS_ERR(inode))
		printk("coda_cnode_make: coda_iget failed\n");
                return PTR_ERR(*inode);
        }
	return 0;
	return inode;
}


@@ -156,19 +153,16 @@ struct inode *coda_fid_to_inode(struct CodaFid *fid, struct super_block *sb)
}

/* the CONTROL inode is made without asking attributes from Venus */
int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
struct inode *coda_cnode_makectl(struct super_block *sb)
{
	int error = -ENOMEM;

	*inode = new_inode(sb);
	if (*inode) {
		(*inode)->i_ino = CTL_INO;
		(*inode)->i_op = &coda_ioctl_inode_operations;
		(*inode)->i_fop = &coda_ioctl_operations;
		(*inode)->i_mode = 0444;
		error = 0;
	struct inode *inode = new_inode(sb);
	if (inode) {
		inode->i_ino = CTL_INO;
		inode->i_op = &coda_ioctl_inode_operations;
		inode->i_fop = &coda_ioctl_operations;
		inode->i_mode = 0444;
		return inode;
	}

	return error;
	return ERR_PTR(-ENOMEM);
}
Loading