From 523334ba508a8baaf5fc9f15fbad9ed04f334f48 Mon Sep 17 00:00:00 2001 From: Yongqiang Yang Date: Thu, 24 Mar 2011 08:48:39 +0800 Subject: [PATCH 01/11] ext3: Fix writepage credits computation for ordered mode Original computation forgets to count writes of indirect block themselves (it only counts with blocks necessary for their allocation) in ordered mode. Acked-by: Amir Goldstein Signed-off-by:Yongqiang Yang Signed-off-by: Jan Kara --- fs/ext3/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index ae94f6d949f5..7f5db46308a5 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -3294,7 +3294,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode) if (ext3_should_journal_data(inode)) ret = 3 * (bpp + indirects) + 2; else - ret = 2 * (bpp + indirects) + 2; + ret = 2 * (bpp + indirects) + indirects + 2; #ifdef CONFIG_QUOTA /* We know that structure was already allocated during dquot_initialize so From b03f24567ce7caf2420b8be4c6eb74c191d59a91 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 31 Mar 2011 18:36:52 +0200 Subject: [PATCH 02/11] quota: Don't write quota info in dquot_commit() There's no reason to write quota info in dquot_commit(). The writing is a relict from the old days when we didn't have dquot_acquire() and dquot_release() and thus dquot_commit() could have created / removed quota structures from the file. These days dquot_commit() only updates usage counters / limits in quota structure and thus there's no need to write quota info. This also fixes an issue with journaling filesystem which didn't reserve enough space in the transaction for write of quota info (it could have been dirty at the time of dquot_commit() because of a race with other operation changing it). CC: stable@kernel.org Reported-and-tested-by: Lukas Czerner Signed-off-by: Jan Kara --- fs/quota/dquot.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index a2a622e079f0..b59ee61f4b9a 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -442,7 +442,7 @@ EXPORT_SYMBOL(dquot_acquire); */ int dquot_commit(struct dquot *dquot) { - int ret = 0, ret2 = 0; + int ret = 0; struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); mutex_lock(&dqopt->dqio_mutex); @@ -454,15 +454,10 @@ int dquot_commit(struct dquot *dquot) spin_unlock(&dq_list_lock); /* Inactive dquot can be only if there was error during read/init * => we have better not writing it */ - if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { + if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); - if (info_dirty(&dqopt->info[dquot->dq_type])) { - ret2 = dqopt->ops[dquot->dq_type]->write_file_info( - dquot->dq_sb, dquot->dq_type); - } - if (ret >= 0) - ret = ret2; - } + else + ret = -EIO; out_sem: mutex_unlock(&dqopt->dqio_mutex); return ret; From 65a94b1417badaee2ed923fd07e23b651b25c729 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Mon, 4 Apr 2011 09:43:29 +0200 Subject: [PATCH 03/11] [S390] oprofile s390: prevent stack corruption Prevent stack corruption by memcpy which copies more bytes then available at the destination. While at it use the new test_facility to test for the facility bit. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky --- arch/s390/oprofile/hwsampler.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c index 3d48f4db246d..4952872d6f0a 100644 --- a/arch/s390/oprofile/hwsampler.c +++ b/arch/s390/oprofile/hwsampler.c @@ -517,12 +517,8 @@ static int stop_sampling(int cpu) static int check_hardware_prerequisites(void) { - unsigned long long facility_bits[2]; - - memcpy(facility_bits, S390_lowcore.stfle_fac_list, 32); - if (!(facility_bits[1] & (1ULL << 59))) + if (!test_facility(68)) return -EOPNOTSUPP; - return 0; } /* From 034e9e966cd86e5d8062cf0b3daba4bde187986c Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Mon, 4 Apr 2011 09:43:30 +0200 Subject: [PATCH 04/11] [S390] Fix parameter passing for smp_switch_to_cpu() After the execution has been switched to the destination CPU, the target function is called with the wrong parameter. According to the C calling convention on s390, the first parameter should be loaded into register 2. Currently in smp_restart_cpu() it is stored in register 3. To fix this, we load the parameter into the correct register 2. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/switch_cpu.S | 4 +++- arch/s390/kernel/switch_cpu64.S | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/switch_cpu.S b/arch/s390/kernel/switch_cpu.S index 469f11b574fa..20530dd2eab1 100644 --- a/arch/s390/kernel/switch_cpu.S +++ b/arch/s390/kernel/switch_cpu.S @@ -46,7 +46,9 @@ smp_restart_cpu: ltr %r4,%r4 /* New stack ? */ jz 1f lr %r15,%r4 -1: basr %r14,%r2 +1: lr %r14,%r2 /* r14: Function to call */ + lr %r2,%r3 /* r2 : Parameter for function*/ + basr %r14,%r14 /* Call function */ .gprregs_addr: .long .gprregs diff --git a/arch/s390/kernel/switch_cpu64.S b/arch/s390/kernel/switch_cpu64.S index d94aacc898cb..5be3f43898f9 100644 --- a/arch/s390/kernel/switch_cpu64.S +++ b/arch/s390/kernel/switch_cpu64.S @@ -42,7 +42,9 @@ smp_restart_cpu: ltgr %r4,%r4 /* New stack ? */ jz 1f lgr %r15,%r4 -1: basr %r14,%r2 +1: lgr %r14,%r2 /* r14: Function to call */ + lgr %r2,%r3 /* r2 : Parameter for function*/ + basr %r14,%r14 /* Call function */ .section .data,"aw",@progbits .gprregs: From aa5c8df398266a141fb5ff0e77cbc7904a3e0648 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 4 Apr 2011 09:43:31 +0200 Subject: [PATCH 05/11] [S390] qdio: fix init sequence Reorder the initialization sequence of the qdio module to avoid writing to an uninitialized debug feature entry. Also reorder the exit function to restore a consistent cleanup path. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio_main.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 479c665e9e7c..c532ba929ccd 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -1649,26 +1649,26 @@ static int __init init_QDIO(void) { int rc; - rc = qdio_setup_init(); + rc = qdio_debug_init(); if (rc) return rc; + rc = qdio_setup_init(); + if (rc) + goto out_debug; rc = tiqdio_allocate_memory(); if (rc) goto out_cache; - rc = qdio_debug_init(); - if (rc) - goto out_ti; rc = tiqdio_register_thinints(); if (rc) - goto out_debug; + goto out_ti; return 0; -out_debug: - qdio_debug_exit(); out_ti: tiqdio_free_memory(); out_cache: qdio_setup_exit(); +out_debug: + qdio_debug_exit(); return rc; } @@ -1676,8 +1676,8 @@ static void __exit exit_QDIO(void) { tiqdio_unregister_thinints(); tiqdio_free_memory(); - qdio_debug_exit(); qdio_setup_exit(); + qdio_debug_exit(); } module_init(init_QDIO); From a2fc8485f838ccd2ce5db690f81ac086489a9e7e Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Mon, 4 Apr 2011 09:43:32 +0200 Subject: [PATCH 06/11] [S390] cio: prevent purging of CCW devices in the online state The cio_ignore purge function is intended to only remove CCW devices which are in the offline state. There is a time frame after the purge function finished where a CCW device is scheduled for removal but still accessible. When the device is set online during this time frame, it may first appear online before it is then removed. Fix this by preventing that CCW devices can be set online while there is work (such as removal triggered by the purge function) for it pending. Also ensure that the purge function does not schedule devices for removal which are in the process of being set online. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/device.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index df14c51f6532..8e04c00cf0ad 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -541,15 +541,24 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr, int force, ret; unsigned long i; - if (!dev_fsm_final_state(cdev) && - cdev->private->state != DEV_STATE_DISCONNECTED) - return -EAGAIN; + /* Prevent conflict between multiple on-/offline processing requests. */ if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0) return -EAGAIN; + /* Prevent conflict between internal I/Os and on-/offline processing. */ + if (!dev_fsm_final_state(cdev) && + cdev->private->state != DEV_STATE_DISCONNECTED) { + ret = -EAGAIN; + goto out_onoff; + } + /* Prevent conflict between pending work and on-/offline processing.*/ + if (work_pending(&cdev->private->todo_work)) { + ret = -EAGAIN; + goto out_onoff; + } if (cdev->drv && !try_module_get(cdev->drv->driver.owner)) { - atomic_set(&cdev->private->onoff, 0); - return -EINVAL; + ret = -EINVAL; + goto out_onoff; } if (!strncmp(buf, "force\n", count)) { force = 1; @@ -574,6 +583,7 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr, out: if (cdev->drv) module_put(cdev->drv->driver.owner); +out_onoff: atomic_set(&cdev->private->onoff, 0); return (ret < 0) ? ret : count; } @@ -1311,10 +1321,12 @@ static int purge_fn(struct device *dev, void *data) spin_lock_irq(cdev->ccwlock); if (is_blacklisted(id->ssid, id->devno) && - (cdev->private->state == DEV_STATE_OFFLINE)) { + (cdev->private->state == DEV_STATE_OFFLINE) && + (atomic_cmpxchg(&cdev->private->onoff, 0, 1) == 0)) { CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", id->ssid, id->devno); ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); + atomic_set(&cdev->private->onoff, 0); } spin_unlock_irq(cdev->ccwlock); /* Abort loop in case of pending signal. */ From 8838101183bba239f100b0cfe31d9ebbfc2f1bd4 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 4 Apr 2011 09:43:33 +0200 Subject: [PATCH 07/11] [S390] compile fix for latest binutils The latest binutils won't accept the stfl instruction with march=g5 which is the correct behaviour. Unfortunately head.S is assembled with -march=g5 even if the target cpu is z900 or later. To get 31-bit kernels compiled again the easiest fix is to use the .insn notation for the stfl instruction in head.S. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index 7061398341d5..fb317bf2c378 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -460,7 +460,7 @@ startup: #ifndef CONFIG_MARCH_G5 # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST - stfl __LC_STFL_FAC_LIST # store facility list + .insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list tm __LC_STFL_FAC_LIST,0x01 # stfle available ? jz 0f la %r0,0 From 0867659fa3c245bf203d837a82e0f6ea5079c2c5 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 6 Apr 2011 10:13:32 -0700 Subject: [PATCH 08/11] Revert "net/sunrpc: Use static const char arrays" This reverts commit 411b5e05617593efebc06241dbc56f42150f2abe. Olga Kornievskaia reports: Problem: linux client mounting linux server using rc4-hmac-md5 enctype. gssd fails with create a context after receiving a reply from the server. Diagnose: putting printout statements in the server kernel and kerberos libraries revealed that client and server derived different integrity keys. Server kernel code was at fault due the the commit [aglo@skydive linux-pnfs]$ git show 411b5e05617593efebc06241dbc56f42150f2abe Trond: The problem is that since it relies on virt_to_page(), you cannot call sg_set_buf() for data in the const section. Reported-by: Olga Kornievskaia Signed-off-by: Trond Myklebust Cc: stable@kernel.org [2.6.36+] --- net/sunrpc/auth_gss/gss_krb5_mech.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 9022f0a6503e..0a9a2ec2e469 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -427,7 +427,7 @@ static int context_derive_keys_rc4(struct krb5_ctx *ctx) { struct crypto_hash *hmac; - static const char sigkeyconstant[] = "signaturekey"; + char sigkeyconstant[] = "signaturekey"; int slen = strlen(sigkeyconstant) + 1; /* include null terminator */ struct hash_desc desc; struct scatterlist sg[1]; From 418875900e3de4831c84f86ae4756690dac5be77 Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Wed, 6 Apr 2011 14:33:28 -0400 Subject: [PATCH 09/11] NFS: Fix a signed vs. unsigned secinfo bug rpc_authflavor_t is cast from an unsigned int, but the initial code tried to use it as a signed int. I fix this by passing an rpc_authflavor_t pointer around, and returning signed integers from functions. Signed-off-by: Bryan Schumaker Reported-by: Dan Carpenter Signed-off-by: Trond Myklebust --- fs/nfs/namespace.c | 58 ++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 9166fcb66da2..89fc160fd5b0 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -148,67 +148,64 @@ static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors, return pseudoflavor; } -static rpc_authflavor_t nfs_negotiate_security(const struct dentry *parent, const struct dentry *dentry) +static int nfs_negotiate_security(const struct dentry *parent, + const struct dentry *dentry, + rpc_authflavor_t *flavor) { - int status = 0; struct page *page; struct nfs4_secinfo_flavors *flavors; int (*secinfo)(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); - rpc_authflavor_t flavor = RPC_AUTH_UNIX; + int ret = -EPERM; secinfo = NFS_PROTO(parent->d_inode)->secinfo; if (secinfo != NULL) { page = alloc_page(GFP_KERNEL); if (!page) { - status = -ENOMEM; + ret = -ENOMEM; goto out; } flavors = page_address(page); - status = secinfo(parent->d_inode, &dentry->d_name, flavors); - flavor = nfs_find_best_sec(flavors, dentry->d_inode); + ret = secinfo(parent->d_inode, &dentry->d_name, flavors); + *flavor = nfs_find_best_sec(flavors, dentry->d_inode); put_page(page); } - return flavor; - out: - status = -ENOMEM; - return status; + return ret; } -static rpc_authflavor_t nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent, - struct dentry *dentry, struct path *path, - struct nfs_fh *fh, struct nfs_fattr *fattr) +static int nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent, + struct dentry *dentry, struct path *path, + struct nfs_fh *fh, struct nfs_fattr *fattr, + rpc_authflavor_t *flavor) { - rpc_authflavor_t flavor; struct rpc_clnt *clone; struct rpc_auth *auth; int err; - flavor = nfs_negotiate_security(parent, path->dentry); - if (flavor < 0) + err = nfs_negotiate_security(parent, path->dentry, flavor); + if (err < 0) goto out; clone = rpc_clone_client(server->client); - auth = rpcauth_create(flavor, clone); + auth = rpcauth_create(*flavor, clone); if (!auth) { - flavor = -EIO; + err = -EIO; goto out_shutdown; } err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode, &path->dentry->d_name, fh, fattr); - if (err < 0) - flavor = err; out_shutdown: rpc_shutdown_client(clone); out: - return flavor; + return err; } #else /* CONFIG_NFS_V4 */ -static inline rpc_authflavor_t nfs_lookup_with_sec(struct nfs_server *server, - struct dentry *parent, struct dentry *dentry, - struct path *path, struct nfs_fh *fh, - struct nfs_fattr *fattr) +static inline int nfs_lookup_with_sec(struct nfs_server *server, + struct dentry *parent, struct dentry *dentry, + struct path *path, struct nfs_fh *fh, + struct nfs_fattr *fattr, + rpc_authflavor_t *flavor) { return -EPERM; } @@ -234,7 +231,7 @@ struct vfsmount *nfs_d_automount(struct path *path) struct nfs_fh *fh = NULL; struct nfs_fattr *fattr = NULL; int err; - rpc_authflavor_t flavor = 1; + rpc_authflavor_t flavor = RPC_AUTH_UNIX; dprintk("--> nfs_d_automount()\n"); @@ -255,13 +252,8 @@ struct vfsmount *nfs_d_automount(struct path *path) err = server->nfs_client->rpc_ops->lookup(server->client, parent->d_inode, &path->dentry->d_name, fh, fattr); - if (err == -EPERM) { - flavor = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr); - if (flavor < 0) - err = flavor; - else - err = 0; - } + if (err == -EPERM && NFS_PROTO(parent->d_inode)->secinfo != NULL) + err = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr, &flavor); dput(parent); if (err != 0) { mnt = ERR_PTR(err); From 37adb89fadd65ce47f7e5cfd564938a76b351948 Mon Sep 17 00:00:00 2001 From: Bryan Schumaker Date: Thu, 7 Apr 2011 16:02:20 -0400 Subject: [PATCH 10/11] NFS: Change initial mount authflavor only when server returns NFS4ERR_WRONGSEC When attempting an initial mount, we should only attempt other authflavors if AUTH_UNIX receives a NFS4ERR_WRONGSEC error. This allows other errors to be passed back to userspace programs. Signed-off-by: Bryan Schumaker Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index dfd1e6d7e6c3..9bf41eab3e46 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2204,8 +2204,6 @@ static int nfs4_lookup_root_sec(struct nfs_server *server, struct nfs_fh *fhandl goto out; } ret = nfs4_lookup_root(server, fhandle, info); - if (ret < 0) - ret = -EAGAIN; out: return ret; } @@ -2226,7 +2224,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, for (i = 0; i < len; i++) { status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]); - if (status == 0) + if (status != -EPERM) break; } if (status == 0) From f9fa0bc1fabe1d861e46d80ecbe7e85da359195c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Apr 2011 10:53:46 -0700 Subject: [PATCH 11/11] signal.c: fix erroneous syscall kernel-doc Fix erroneous syscall kernel-doc comments in kernel/signal.c. Reported-by: Matt Fleming Signed-off-by: Randy Dunlap Signed-off-by: Linus Torvalds --- kernel/signal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index 29e233fd7a0f..7165af5f1b11 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2711,8 +2711,8 @@ SYSCALL_DEFINE3(sigprocmask, int, how, old_sigset_t __user *, set, /** * sys_rt_sigaction - alter an action taken by a process * @sig: signal to be sent - * @act: the thread group ID of the thread - * @oact: the PID of the thread + * @act: new sigaction + * @oact: used to save the previous sigaction * @sigsetsize: size of sigset_t type */ SYSCALL_DEFINE4(rt_sigaction, int, sig,