From 7f62656be8a8ef14c168db2d98021fb9c8cc1076 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Nov 2013 10:49:40 +0300 Subject: aio: checking for NULL instead of IS_ERR alloc_anon_inode() returns an ERR_PTR(), it doesn't return NULL. Fixes: 71ad7490c1f3 ('rework aio migrate pages to use aio fs') Signed-off-by: Dan Carpenter Signed-off-by: Al Viro diff --git a/fs/aio.c b/fs/aio.c index 1f602d9..823efcb 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -163,8 +163,8 @@ static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) struct file *file; struct path path; struct inode *inode = alloc_anon_inode(aio_mnt->mnt_sb); - if (!inode) - return ERR_PTR(-ENOMEM); + if (IS_ERR(inode)) + return ERR_CAST(inode); inode->i_mapping->a_ops = &aio_ctx_aops; inode->i_mapping->private_data = ctx; -- cgit v0.10.2 From 4fdb793ffe262cfc0b796d3b2cd05ca3b687deb9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Nov 2013 10:56:27 +0300 Subject: locks: missing unlock on error in generic_add_lease() We should unlock here before returning. Fixes: df4e8d2c1d2b ('locks: implement delegations') Signed-off-by: Dan Carpenter Signed-off-by: Al Viro diff --git a/fs/locks.c b/fs/locks.c index f99d52b..92a0f0a 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1494,6 +1494,7 @@ static int generic_add_lease(struct file *filp, long arg, struct file_lock **flp if (is_deleg && arg == F_WRLCK) { /* Write delegations are not currently supported: */ + mutex_unlock(&inode->i_mutex); WARN_ON_ONCE(1); return -EINVAL; } -- cgit v0.10.2 From 4ec6c2aeab8a909418ac60b782a963cb7257207f Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Wed, 13 Nov 2013 15:21:51 +0800 Subject: fix unpaired rcu lock in prepend_path() Signed-off-by: Li Zhong Signed-off-by: Al Viro diff --git a/fs/dcache.c b/fs/dcache.c index 1f24cd6..eacc853 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2924,6 +2924,7 @@ static int prepend_path(const struct path *path, restart_mnt: read_seqbegin_or_lock(&mount_lock, &m_seq); seq = 0; + rcu_read_lock(); restart: bptr = *buffer; blen = *buflen; @@ -2971,6 +2972,9 @@ restart: goto restart; } done_seqretry(&rename_lock, seq); + + if (!(m_seq & 1)) + rcu_read_unlock(); if (need_seqretry(&mount_lock, m_seq)) { m_seq = 1; goto restart_mnt; -- cgit v0.10.2 From ede4cebce16f5643c61aedd6d88d9070a1d23a68 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 13 Nov 2013 07:45:40 -0500 Subject: prepend_path() needs to reinitialize dentry/vfsmount/mnt on restarts ... and equivalent is needed in 3.12; it's broken there as well Signed-off-by: Al Viro diff --git a/fs/dcache.c b/fs/dcache.c index eacc853..a9dd384 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2912,9 +2912,9 @@ static int prepend_path(const struct path *path, const struct path *root, char **buffer, int *buflen) { - struct dentry *dentry = path->dentry; - struct vfsmount *vfsmnt = path->mnt; - struct mount *mnt = real_mount(vfsmnt); + struct dentry *dentry; + struct vfsmount *vfsmnt; + struct mount *mnt; int error = 0; unsigned seq, m_seq = 0; char *bptr; @@ -2929,6 +2929,9 @@ restart: bptr = *buffer; blen = *buflen; error = 0; + dentry = path->dentry; + vfsmnt = path->mnt; + mnt = real_mount(vfsmnt); read_seqbegin_or_lock(&rename_lock, &seq); while (dentry != root->dentry || vfsmnt != root->mnt) { struct dentry * parent; -- cgit v0.10.2 From 441a9d0e1e827e6433e3487145fbb0c5513301e2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 13 Nov 2013 07:52:33 -0500 Subject: qib_fs: fix (some) dcache abuses * lookup_one_len() really wants i_mutex held on directory. * leaks galore - just mount ipathfs, then cd /sys/bus/pci/drivers/qib_ib; echo *:*:*.* >unbind on a box with that card present and try to umount ipathfs... Signed-off-by: Al Viro diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index f247fc6e..c61e2a9 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c @@ -456,13 +456,13 @@ static int remove_file(struct dentry *parent, char *name) spin_lock(&tmp->d_lock); if (!(d_unhashed(tmp) && tmp->d_inode)) { - dget_dlock(tmp); __d_drop(tmp); spin_unlock(&tmp->d_lock); simple_unlink(parent->d_inode, tmp); } else { spin_unlock(&tmp->d_lock); } + dput(tmp); ret = 0; bail: @@ -491,6 +491,7 @@ static int remove_device_files(struct super_block *sb, goto bail; } + mutex_lock(&dir->d_inode->i_mutex); remove_file(dir, "counters"); remove_file(dir, "counter_names"); remove_file(dir, "portcounter_names"); @@ -505,8 +506,10 @@ static int remove_device_files(struct super_block *sb, } } remove_file(dir, "flash"); - d_delete(dir); + mutex_unlock(&dir->d_inode->i_mutex); ret = simple_rmdir(root->d_inode, dir); + d_delete(dir); + dput(dir); bail: mutex_unlock(&root->d_inode->i_mutex); -- cgit v0.10.2