From 58763148758057ffc447bf990321d3ea86d199a0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 30 Aug 2016 10:15:03 +0200 Subject: perf/core: Remove WARN from perf_event_read() This effectively reverts commit: 71e7bc2bab77 ("perf/core: Check return value of the perf_event_read() IPI") ... and puts in a comment explaining why we ignore the return value. Reported-by: Vegard Nossum Signed-off-by: Peter Zijlstra (Intel) Cc: David Carrillo-Cisneros Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Fixes: 71e7bc2bab77 ("perf/core: Check return value of the perf_event_read() IPI") Signed-off-by: Ingo Molnar --- kernel/events/core.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/events/core.c b/kernel/events/core.c index 3cfabdf7b942..07ac8596a728 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3549,10 +3549,18 @@ static int perf_event_read(struct perf_event *event, bool group) .group = group, .ret = 0, }; - ret = smp_call_function_single(event->oncpu, __perf_event_read, &data, 1); - /* The event must have been read from an online CPU: */ - WARN_ON_ONCE(ret); - ret = ret ? : data.ret; + /* + * Purposely ignore the smp_call_function_single() return + * value. + * + * If event->oncpu isn't a valid CPU it means the event got + * scheduled out and that will have updated the event count. + * + * Therefore, either way, we'll have an up-to-date event count + * after this. + */ + (void)smp_call_function_single(event->oncpu, __perf_event_read, &data, 1); + ret = data.ret; } else if (event->state == PERF_EVENT_STATE_INACTIVE) { struct perf_event_context *ctx = event->ctx; unsigned long flags; -- cgit v1.2.3 From 135e8c9250dd5c8c9aae5984fde6f230d0cbfeaf Mon Sep 17 00:00:00 2001 From: Balbir Singh Date: Mon, 5 Sep 2016 13:16:40 +1000 Subject: sched/core: Fix a race between try_to_wake_up() and a woken up task The origin of the issue I've seen is related to a missing memory barrier between check for task->state and the check for task->on_rq. The task being woken up is already awake from a schedule() and is doing the following: do { schedule() set_current_state(TASK_(UN)INTERRUPTIBLE); } while (!cond); The waker, actually gets stuck doing the following in try_to_wake_up(): while (p->on_cpu) cpu_relax(); Analysis: The instance I've seen involves the following race: CPU1 CPU2 while () { if (cond) break; do { schedule(); set_current_state(TASK_UN..) } while (!cond); wakeup_routine() spin_lock_irqsave(wait_lock) raw_spin_lock_irqsave(wait_lock) wake_up_process() } try_to_wake_up() set_current_state(TASK_RUNNING); .. list_del(&waiter.list); CPU2 wakes up CPU1, but before it can get the wait_lock and set current state to TASK_RUNNING the following occurs: CPU3 wakeup_routine() raw_spin_lock_irqsave(wait_lock) if (!list_empty) wake_up_process() try_to_wake_up() raw_spin_lock_irqsave(p->pi_lock) .. if (p->on_rq && ttwu_wakeup()) .. while (p->on_cpu) cpu_relax() .. CPU3 tries to wake up the task on CPU1 again since it finds it on the wait_queue, CPU1 is spinning on wait_lock, but immediately after CPU2, CPU3 got it. CPU3 checks the state of p on CPU1, it is TASK_UNINTERRUPTIBLE and the task is spinning on the wait_lock. Interestingly since p->on_rq is checked under pi_lock, I've noticed that try_to_wake_up() finds p->on_rq to be 0. This was the most confusing bit of the analysis, but p->on_rq is changed under runqueue lock, rq_lock, the p->on_rq check is not reliable without this fix IMHO. The race is visible (based on the analysis) only when ttwu_queue() does a remote wakeup via ttwu_queue_remote. In which case the p->on_rq change is not done uder the pi_lock. The result is that after a while the entire system locks up on the raw_spin_irqlock_save(wait_lock) and the holder spins infintely Reproduction of the issue: The issue can be reproduced after a long run on my system with 80 threads and having to tweak available memory to very low and running memory stress-ng mmapfork test. It usually takes a long time to reproduce. I am trying to work on a test case that can reproduce the issue faster, but thats work in progress. I am still testing the changes on my still in a loop and the tests seem OK thus far. Big thanks to Benjamin and Nick for helping debug this as well. Ben helped catch the missing barrier, Nick caught every missing bit in my theory. Signed-off-by: Balbir Singh [ Updated comment to clarify matching barriers. Many architectures do not have a full barrier in switch_to() so that cannot be relied upon. ] Signed-off-by: Peter Zijlstra (Intel) Acked-by: Benjamin Herrenschmidt Cc: Alexey Kardashevskiy Cc: Linus Torvalds Cc: Nicholas Piggin Cc: Nicholas Piggin Cc: Oleg Nesterov Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Link: http://lkml.kernel.org/r/e02cce7b-d9ca-1ad0-7a61-ea97c7582b37@gmail.com Signed-off-by: Ingo Molnar --- kernel/sched/core.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'kernel') diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 2a906f20fba7..44817c640e99 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2016,6 +2016,28 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) success = 1; /* we're going to change ->state */ cpu = task_cpu(p); + /* + * Ensure we load p->on_rq _after_ p->state, otherwise it would + * be possible to, falsely, observe p->on_rq == 0 and get stuck + * in smp_cond_load_acquire() below. + * + * sched_ttwu_pending() try_to_wake_up() + * [S] p->on_rq = 1; [L] P->state + * UNLOCK rq->lock -----. + * \ + * +--- RMB + * schedule() / + * LOCK rq->lock -----' + * UNLOCK rq->lock + * + * [task p] + * [S] p->state = UNINTERRUPTIBLE [L] p->on_rq + * + * Pairs with the UNLOCK+LOCK on rq->lock from the + * last wakeup of our task and the schedule that got our task + * current. + */ + smp_rmb(); if (p->on_rq && ttwu_remote(p, wake_flags)) goto stat; -- cgit v1.2.3 From 767ae08678c2c796bcd7f582ee457aee20a28a1e Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 6 Sep 2016 16:23:49 +0300 Subject: perf/core: Fix a race between mmap_close() and set_output() of AUX events In the mmap_close() path we need to stop all the AUX events that are writing data to the AUX area that we are unmapping, before we can safely free the pages. To determine if an event needs to be stopped, we're comparing its ->rb against the one that's getting unmapped. However, a SET_OUTPUT ioctl may turn up inside an AUX transaction and swizzle event::rb to some other ring buffer, but the transaction will keep writing data to the old ring buffer until the event gets scheduled out. At this point, mmap_close() will skip over such an event and will proceed to free the AUX area, while it's still being used by this event, which will set off a warning in the mmap_close() path and cause a memory corruption. To avoid this, always stop an AUX event before its ->rb is updated; this will release the (potentially) last reference on the AUX area of the buffer. If the event gets restarted, its new ring buffer will be used. If another SET_OUTPUT comes and switches it back to the old ring buffer that's getting unmapped, it's also fine: this ring buffer's aux_mmap_count will be zero and AUX transactions won't start any more. Reported-by: Vince Weaver Signed-off-by: Alexander Shishkin Signed-off-by: Peter Zijlstra (Intel) Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: vince@deater.net Link: http://lkml.kernel.org/r/20160906132353.19887-2-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar --- kernel/events/core.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/events/core.c b/kernel/events/core.c index 07ac8596a728..a54f2c2cdb20 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -2496,11 +2496,11 @@ static int __perf_event_stop(void *info) return 0; } -static int perf_event_restart(struct perf_event *event) +static int perf_event_stop(struct perf_event *event, int restart) { struct stop_event_data sd = { .event = event, - .restart = 1, + .restart = restart, }; int ret = 0; @@ -4845,6 +4845,19 @@ static void ring_buffer_attach(struct perf_event *event, spin_unlock_irqrestore(&rb->event_lock, flags); } + /* + * Avoid racing with perf_mmap_close(AUX): stop the event + * before swizzling the event::rb pointer; if it's getting + * unmapped, its aux_mmap_count will be 0 and it won't + * restart. See the comment in __perf_pmu_output_stop(). + * + * Data will inevitably be lost when set_output is done in + * mid-air, but then again, whoever does it like this is + * not in for the data anyway. + */ + if (has_aux(event)) + perf_event_stop(event, 0); + rcu_assign_pointer(event->rb, rb); if (old_rb) { @@ -6120,7 +6133,7 @@ static void perf_event_addr_filters_exec(struct perf_event *event, void *data) raw_spin_unlock_irqrestore(&ifh->lock, flags); if (restart) - perf_event_restart(event); + perf_event_stop(event, 1); } void perf_event_exec(void) @@ -6164,7 +6177,13 @@ static void __perf_event_output_stop(struct perf_event *event, void *data) /* * In case of inheritance, it will be the parent that links to the - * ring-buffer, but it will be the child that's actually using it: + * ring-buffer, but it will be the child that's actually using it. + * + * We are using event::rb to determine if the event should be stopped, + * however this may race with ring_buffer_attach() (through set_output), + * which will make us skip the event that actually needs to be stopped. + * So ring_buffer_attach() has to stop an aux event before re-assigning + * its rb pointer. */ if (rcu_dereference(parent->rb) == rb) ro->err = __perf_event_stop(&sd); @@ -6678,7 +6697,7 @@ static void __perf_addr_filters_adjust(struct perf_event *event, void *data) raw_spin_unlock_irqrestore(&ifh->lock, flags); if (restart) - perf_event_restart(event); + perf_event_stop(event, 1); } /* @@ -7867,7 +7886,7 @@ static void perf_event_addr_filters_apply(struct perf_event *event) mmput(mm); restart: - perf_event_restart(event); + perf_event_stop(event, 1); } /* -- cgit v1.2.3 From b79ccadd6bb10e72cf784a298ca6dc1398eb9a24 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 6 Sep 2016 16:23:50 +0300 Subject: perf/core: Fix aux_mmap_count vs aux_refcount order The order of accesses to ring buffer's aux_mmap_count and aux_refcount has to be preserved across the users, namely perf_mmap_close() and perf_aux_output_begin(), otherwise the inversion can result in the latter holding the last reference to the aux buffer and subsequently free'ing it in atomic context, triggering a warning. > ------------[ cut here ]------------ > WARNING: CPU: 0 PID: 257 at kernel/events/ring_buffer.c:541 __rb_free_aux+0x11a/0x130 > CPU: 0 PID: 257 Comm: stopbug Not tainted 4.8.0-rc1+ #2596 > Call Trace: > [] __warn+0xcb/0xf0 > [] warn_slowpath_null+0x1d/0x20 > [] __rb_free_aux+0x11a/0x130 > [] rb_free_aux+0x18/0x20 > [] perf_aux_output_begin+0x163/0x1e0 > [] bts_event_start+0x3a/0xd0 > [] bts_event_add+0x5d/0x80 > [] event_sched_in.isra.104+0xf6/0x2f0 > [] group_sched_in+0x6e/0x190 > [] ctx_sched_in+0x2fe/0x5f0 > [] perf_event_sched_in+0x60/0x80 > [] ctx_resched+0x5b/0x90 > [] __perf_event_enable+0x1e1/0x240 > [] event_function+0xa9/0x180 > [] ? perf_cgroup_attach+0x70/0x70 > [] remote_function+0x3f/0x50 > [] flush_smp_call_function_queue+0x83/0x150 > [] generic_smp_call_function_single_interrupt+0x13/0x60 > [] smp_call_function_single_interrupt+0x27/0x40 > [] call_function_single_interrupt+0x89/0x90 > [] finish_task_switch+0xa6/0x210 > [] ? finish_task_switch+0x67/0x210 > [] __schedule+0x3dd/0xb50 > [] schedule+0x35/0x80 > [] sys_sched_yield+0x61/0x70 > [] entry_SYSCALL_64_fastpath+0x18/0xa8 > ---[ end trace 6235f556f5ea83a9 ]--- This patch puts the checks in perf_aux_output_begin() in the same order as that of perf_mmap_close(). Reported-by: Vince Weaver Signed-off-by: Alexander Shishkin Signed-off-by: Peter Zijlstra (Intel) Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: vince@deater.net Link: http://lkml.kernel.org/r/20160906132353.19887-3-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar --- kernel/events/ring_buffer.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c index ae9b90dc9a5a..257fa460b846 100644 --- a/kernel/events/ring_buffer.c +++ b/kernel/events/ring_buffer.c @@ -330,15 +330,22 @@ void *perf_aux_output_begin(struct perf_output_handle *handle, if (!rb) return NULL; - if (!rb_has_aux(rb) || !atomic_inc_not_zero(&rb->aux_refcount)) + if (!rb_has_aux(rb)) goto err; /* - * If rb::aux_mmap_count is zero (and rb_has_aux() above went through), - * the aux buffer is in perf_mmap_close(), about to get freed. + * If aux_mmap_count is zero, the aux buffer is in perf_mmap_close(), + * about to get freed, so we leave immediately. + * + * Checking rb::aux_mmap_count and rb::refcount has to be done in + * the same order, see perf_mmap_close. Otherwise we end up freeing + * aux pages in this path, which is a bug, because in_atomic(). */ if (!atomic_read(&rb->aux_mmap_count)) - goto err_put; + goto err; + + if (!atomic_inc_not_zero(&rb->aux_refcount)) + goto err; /* * Nesting is not supported for AUX area, make sure nested -- cgit v1.2.3 From 1984e075915cbae65336a99b1879865080d8e55e Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 19 Sep 2016 09:49:27 +0100 Subject: genirq: Skip chained interrupt trigger setup if type is IRQ_TYPE_NONE There is no point in trying to configure the trigger of a chained interrupt if no trigger information has been configured. At best this is ignored, and at the worse this confuses the underlying irqchip (which is likely not to handle such a thing), and unnecessarily alarms the user. Only apply the configuration if type is not IRQ_TYPE_NONE. Fixes: 1e12c4a9393b ("genirq: Correctly configure the trigger on chained interrupts") Reported-and-tested-by: Geert Uytterhoeven Signed-off-by: Marc Zyngier Link: https://lkml.kernel.org/r/CAMuHMdVW1eTn20=EtYcJ8hkVwohaSuH_yQXrY2MGBEvZ8fpFOg@mail.gmail.com Link: http://lkml.kernel.org/r/1474274967-15984-1-git-send-email-marc.zyngier@arm.com Signed-off-by: Thomas Gleixner --- kernel/irq/chip.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'kernel') diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 637389088b3f..26ba5654d9d5 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -820,6 +820,8 @@ __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle, desc->name = name; if (handle != handle_bad_irq && is_chained) { + unsigned int type = irqd_get_trigger_type(&desc->irq_data); + /* * We're about to start this interrupt immediately, * hence the need to set the trigger configuration. @@ -828,8 +830,10 @@ __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle, * chained interrupt. Reset it immediately because we * do know better. */ - __irq_set_trigger(desc, irqd_get_trigger_type(&desc->irq_data)); - desc->handle_irq = handle; + if (type != IRQ_TYPE_NONE) { + __irq_set_trigger(desc, type); + desc->handle_irq = handle; + } irq_settings_set_noprobe(desc); irq_settings_set_norequest(desc); -- cgit v1.2.3 From d979a39d7242e0601bf9b60e89628fb8ac577179 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Mon, 19 Sep 2016 14:44:38 -0700 Subject: cgroup: duplicate cgroup reference when cloning sockets When a socket is cloned, the associated sock_cgroup_data is duplicated but not its reference on the cgroup. As a result, the cgroup reference count will underflow when both sockets are destroyed later on. Fixes: bd1060a1d671 ("sock, cgroup: add sock->sk_cgroup") Link: http://lkml.kernel.org/r/20160914194846.11153-2-hannes@cmpxchg.org Signed-off-by: Johannes Weiner Acked-by: Tejun Heo Cc: Michal Hocko Cc: Vladimir Davydov Cc: [4.5+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/cgroup.c | 6 ++++++ net/core/sock.c | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/cgroup.c b/kernel/cgroup.c index d1c51b7f5221..5e8dab5bf9ad 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -6270,6 +6270,12 @@ void cgroup_sk_alloc(struct sock_cgroup_data *skcd) if (cgroup_sk_alloc_disabled) return; + /* Socket clone path */ + if (skcd->val) { + cgroup_get(sock_cgroup_ptr(skcd)); + return; + } + rcu_read_lock(); while (true) { diff --git a/net/core/sock.c b/net/core/sock.c index 25dab8b60223..fd7b41edf1ce 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1362,7 +1362,6 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, if (!try_module_get(prot->owner)) goto out_free_sec; sk_tx_queue_clear(sk); - cgroup_sk_alloc(&sk->sk_cgrp_data); } return sk; @@ -1422,6 +1421,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, sock_net_set(sk, net); atomic_set(&sk->sk_wmem_alloc, 1); + cgroup_sk_alloc(&sk->sk_cgrp_data); sock_update_classid(&sk->sk_cgrp_data); sock_update_netprioidx(&sk->sk_cgrp_data); } @@ -1566,6 +1566,9 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) newsk->sk_priority = 0; newsk->sk_incoming_cpu = raw_smp_processor_id(); atomic64_set(&newsk->sk_cookie, 0); + + cgroup_sk_alloc(&newsk->sk_cgrp_data); + /* * Before updating sk_refcnt, we must commit prior changes to memory * (Documentation/RCU/rculist_nulls.txt for details) -- cgit v1.2.3 From 3bf6215a1b30db7df6083c708caab3fe1a8e8abe Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Tue, 20 Sep 2016 18:48:11 +0300 Subject: perf/core: Limit matching exclusive events to one PMU An "exclusive" PMU is the one that can only have one event scheduled in at any given time. There may be more than one of such PMUs in a system, though, like Intel PT and BTS. It should be allowed to have one event for either of those inside the same context (there may be other constraints that may prevent this, but those would be hardware-specific). However, the exclusivity code is written so that only one event from any of the "exclusive" PMUs is allowed in a context. Fix this by making the exclusive event filter explicitly match two events' PMUs. Signed-off-by: Alexander Shishkin Acked-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Cc: vince@deater.net Link: http://lkml.kernel.org/r/20160920154811.3255-3-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar --- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/events/core.c b/kernel/events/core.c index a54f2c2cdb20..fc9bb2225291 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3929,7 +3929,7 @@ static void exclusive_event_destroy(struct perf_event *event) static bool exclusive_event_match(struct perf_event *e1, struct perf_event *e2) { - if ((e1->pmu->capabilities & PERF_PMU_CAP_EXCLUSIVE) && + if ((e1->pmu == e2->pmu) && (e1->cpu == e2->cpu || e1->cpu == -1 || e2->cpu == -1)) -- cgit v1.2.3 From 1245800c0f96eb6ebb368593e251d66c01e61022 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 23 Sep 2016 22:57:13 -0400 Subject: tracing: Move mutex to protect against resetting of seq data The iter->seq can be reset outside the protection of the mutex. So can reading of user data. Move the mutex up to the beginning of the function. Fixes: d7350c3f45694 ("tracing/core: make the read callbacks reentrants") Cc: stable@vger.kernel.org # 2.6.30+ Reported-by: Al Viro Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8a4bd6b68a0b..8fb4847b0450 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4890,19 +4890,20 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, struct trace_iterator *iter = filp->private_data; ssize_t sret; - /* return any leftover data */ - sret = trace_seq_to_user(&iter->seq, ubuf, cnt); - if (sret != -EBUSY) - return sret; - - trace_seq_init(&iter->seq); - /* * Avoid more than one consumer on a single file descriptor * This is just a matter of traces coherency, the ring buffer itself * is protected. */ mutex_lock(&iter->mutex); + + /* return any leftover data */ + sret = trace_seq_to_user(&iter->seq, ubuf, cnt); + if (sret != -EBUSY) + goto out; + + trace_seq_init(&iter->seq); + if (iter->trace->read) { sret = iter->trace->read(iter, filp, ubuf, cnt, ppos); if (sret) -- cgit v1.2.3 From 1ae2293dd6d2f5c823cf97e60b70d03631cd622f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 17 Sep 2016 18:31:46 -0400 Subject: fix memory leaks in tracing_buffers_splice_read() Cc: stable@vger.kernel.org Signed-off-by: Al Viro --- kernel/trace/trace.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 8fb4847b0450..77eeab2776ef 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -5930,9 +5930,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, return -EBUSY; #endif - if (splice_grow_spd(pipe, &spd)) - return -ENOMEM; - if (*ppos & (PAGE_SIZE - 1)) return -EINVAL; @@ -5942,6 +5939,9 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, len &= PAGE_MASK; } + if (splice_grow_spd(pipe, &spd)) + return -ENOMEM; + again: trace_access_lock(iter->cpu_file); entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file); @@ -5999,19 +5999,21 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, /* did we read anything? */ if (!spd.nr_pages) { if (ret) - return ret; + goto out; + ret = -EAGAIN; if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK)) - return -EAGAIN; + goto out; ret = wait_on_pipe(iter, true); if (ret) - return ret; + goto out; goto again; } ret = splice_to_pipe(pipe, &spd); +out: splice_shrink_spd(&spd); return ret; -- cgit v1.2.3 From e0e0be8a835520e2f7c89f214dfda570922a1b90 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 27 Sep 2016 11:03:57 +0200 Subject: libfs: support RENAME_NOREPLACE in simple_rename() This is trivial to do: - add flags argument to simple_rename() - check if flags doesn't have any other than RENAME_NOREPLACE - assign simple_rename() to .rename2 instead of .rename Filesystems converted: hugetlbfs, ramfs, bpf. Debugfs uses simple_rename() to implement debugfs_rename(), which is for debugfs instances to rename files internally, not for userspace filesystem access. For this case pass zero flags to simple_rename(). Signed-off-by: Miklos Szeredi Acked-by: Greg Kroah-Hartman Cc: Alexei Starovoitov --- fs/debugfs/inode.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/libfs.c | 6 +++++- fs/ramfs/inode.c | 2 +- include/linux/fs.h | 3 ++- kernel/bpf/inode.c | 2 +- 6 files changed, 11 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 72361baf9da7..5ac27c9de669 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -748,7 +748,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, old_name = fsnotify_oldname_init(old_dentry->d_name.name); error = simple_rename(d_inode(old_dir), old_dentry, d_inode(new_dir), - dentry); + dentry, 0); if (error) { fsnotify_oldname_free(old_name); goto exit; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 4ea71eba40a5..50cd7475a942 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -988,7 +988,7 @@ static const struct inode_operations hugetlbfs_dir_inode_operations = { .mkdir = hugetlbfs_mkdir, .rmdir = simple_rmdir, .mknod = hugetlbfs_mknod, - .rename = simple_rename, + .rename2 = simple_rename, .setattr = hugetlbfs_setattr, }; diff --git a/fs/libfs.c b/fs/libfs.c index 74dc8b9e7f53..4758353b2d41 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -349,11 +349,15 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry) EXPORT_SYMBOL(simple_rmdir); int simple_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) { struct inode *inode = d_inode(old_dentry); int they_are_dirs = d_is_dir(old_dentry); + if (flags & ~RENAME_NOREPLACE) + return -EINVAL; + if (!simple_empty(new_dentry)) return -ENOTEMPTY; diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 1ab6e6c2e60e..c2aa068ff974 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -146,7 +146,7 @@ static const struct inode_operations ramfs_dir_inode_operations = { .mkdir = ramfs_mkdir, .rmdir = simple_rmdir, .mknod = ramfs_mknod, - .rename = simple_rename, + .rename2 = simple_rename, }; static const struct super_operations ramfs_ops = { diff --git a/include/linux/fs.h b/include/linux/fs.h index 901e25d495cc..2bd67545fdf8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2950,7 +2950,8 @@ extern int simple_open(struct inode *inode, struct file *file); extern int simple_link(struct dentry *, struct inode *, struct dentry *); extern int simple_unlink(struct inode *, struct dentry *); extern int simple_rmdir(struct inode *, struct dentry *); -extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); +extern int simple_rename(struct inode *, struct dentry *, + struct inode *, struct dentry *, unsigned int); extern int noop_fsync(struct file *, loff_t, loff_t, int); extern int simple_empty(struct dentry *); extern int simple_readpage(struct file *file, struct page *page); diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index 5967b870a895..c92fd8936d33 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c @@ -189,7 +189,7 @@ static const struct inode_operations bpf_dir_iops = { .mknod = bpf_mkobj, .mkdir = bpf_mkdir, .rmdir = simple_rmdir, - .rename = simple_rename, + .rename2 = simple_rename, .link = simple_link, .unlink = simple_unlink, }; -- cgit v1.2.3 From 2773bf00aeb9bf39e022463272a61dd0ec9f55f4 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 27 Sep 2016 11:03:58 +0200 Subject: fs: rename "rename2" i_op to "rename" Generated patch: sed -i "s/\.rename2\t/\.rename\t\t/" `git grep -wl rename2` sed -i "s/\brename2\b/rename/g" `git grep -wl rename2` Signed-off-by: Miklos Szeredi --- Documentation/filesystems/Locking | 6 +++--- Documentation/filesystems/vfs.txt | 2 +- drivers/staging/lustre/lustre/llite/namei.c | 2 +- fs/9p/vfs_inode.c | 4 ++-- fs/9p/vfs_inode_dotl.c | 2 +- fs/affs/dir.c | 2 +- fs/afs/dir.c | 2 +- fs/bad_inode.c | 2 +- fs/bfs/dir.c | 2 +- fs/btrfs/inode.c | 2 +- fs/cachefiles/namei.c | 2 +- fs/ceph/dir.c | 4 ++-- fs/cifs/cifsfs.c | 2 +- fs/coda/dir.c | 2 +- fs/ecryptfs/inode.c | 2 +- fs/exofs/namei.c | 2 +- fs/ext2/namei.c | 2 +- fs/ext4/namei.c | 2 +- fs/f2fs/namei.c | 2 +- fs/fat/namei_msdos.c | 2 +- fs/fat/namei_vfat.c | 2 +- fs/fuse/dir.c | 2 +- fs/gfs2/inode.c | 2 +- fs/hfs/dir.c | 2 +- fs/hfsplus/dir.c | 2 +- fs/hostfs/hostfs_kern.c | 2 +- fs/hpfs/namei.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/jffs2/dir.c | 2 +- fs/jfs/namei.c | 2 +- fs/kernfs/dir.c | 2 +- fs/logfs/dir.c | 2 +- fs/minix/namei.c | 2 +- fs/namei.c | 4 ++-- fs/ncpfs/dir.c | 2 +- fs/nfs/nfs3proc.c | 2 +- fs/nfs/nfs4proc.c | 2 +- fs/nfs/proc.c | 2 +- fs/nilfs2/namei.c | 2 +- fs/ocfs2/namei.c | 2 +- fs/omfs/dir.c | 2 +- fs/orangefs/namei.c | 2 +- fs/overlayfs/dir.c | 2 +- fs/overlayfs/overlayfs.h | 4 ++-- fs/ramfs/inode.c | 2 +- fs/reiserfs/namei.c | 2 +- fs/sysv/namei.c | 2 +- fs/ubifs/dir.c | 2 +- fs/udf/namei.c | 2 +- fs/ufs/namei.c | 2 +- fs/xfs/xfs_iops.c | 4 ++-- include/linux/fs.h | 2 +- kernel/bpf/inode.c | 2 +- mm/shmem.c | 2 +- security/tomoyo/realpath.c | 4 ++-- 55 files changed, 63 insertions(+), 63 deletions(-) (limited to 'kernel') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index da320bc08b9e..fe15682e8acd 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -50,7 +50,7 @@ prototypes: int (*mkdir) (struct inode *,struct dentry *,umode_t); int (*rmdir) (struct inode *,struct dentry *); int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t); - int (*rename2) (struct inode *, struct dentry *, + int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *, unsigned int); int (*readlink) (struct dentry *, char __user *,int); const char *(*get_link) (struct dentry *, struct inode *, void **); @@ -81,7 +81,7 @@ symlink: yes mkdir: yes unlink: yes (both) rmdir: yes (both) (see below) -rename2: yes (all) (see below) +rename: yes (all) (see below) readlink: no get_link: no setattr: yes @@ -99,7 +99,7 @@ tmpfile: no Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on victim. - cross-directory ->rename2() has (per-superblock) ->s_vfs_rename_sem. + cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. See Documentation/filesystems/directory-locking for more detailed discussion of the locking scheme for directory operations. diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index c641e0c37a07..b6bfa0bc02f8 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -345,7 +345,7 @@ struct inode_operations { int (*mkdir) (struct inode *,struct dentry *,umode_t); int (*rmdir) (struct inode *,struct dentry *); int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t); - int (*rename2) (struct inode *, struct dentry *, + int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *, unsigned int); int (*readlink) (struct dentry *, char __user *,int); const char *(*get_link) (struct dentry *, struct inode *, diff --git a/drivers/staging/lustre/lustre/llite/namei.c b/drivers/staging/lustre/lustre/llite/namei.c index ec824db2ad33..a603f29349f9 100644 --- a/drivers/staging/lustre/lustre/llite/namei.c +++ b/drivers/staging/lustre/lustre/llite/namei.c @@ -1106,7 +1106,7 @@ const struct inode_operations ll_dir_inode_operations = { .rmdir = ll_rmdir, .symlink = ll_symlink, .link = ll_link, - .rename2 = ll_rename, + .rename = ll_rename, .setattr = ll_setattr, .getattr = ll_getattr, .permission = ll_inode_permission, diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 50ab1a615207..0ad3c6c712b8 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -1440,7 +1440,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = { .mkdir = v9fs_vfs_mkdir, .rmdir = v9fs_vfs_rmdir, .mknod = v9fs_vfs_mknod, - .rename2 = v9fs_vfs_rename, + .rename = v9fs_vfs_rename, .getattr = v9fs_vfs_getattr, .setattr = v9fs_vfs_setattr, }; @@ -1453,7 +1453,7 @@ static const struct inode_operations v9fs_dir_inode_operations = { .mkdir = v9fs_vfs_mkdir, .rmdir = v9fs_vfs_rmdir, .mknod = v9fs_vfs_mknod, - .rename2 = v9fs_vfs_rename, + .rename = v9fs_vfs_rename, .getattr = v9fs_vfs_getattr, .setattr = v9fs_vfs_setattr, }; diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 8164be972b5c..eeabcb0bad12 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -964,7 +964,7 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = { .mkdir = v9fs_vfs_mkdir_dotl, .rmdir = v9fs_vfs_rmdir, .mknod = v9fs_vfs_mknod_dotl, - .rename2 = v9fs_vfs_rename, + .rename = v9fs_vfs_rename, .getattr = v9fs_vfs_getattr_dotl, .setattr = v9fs_vfs_setattr_dotl, .setxattr = generic_setxattr, diff --git a/fs/affs/dir.c b/fs/affs/dir.c index 8f127c239472..f1e7294381c5 100644 --- a/fs/affs/dir.c +++ b/fs/affs/dir.c @@ -35,7 +35,7 @@ const struct inode_operations affs_dir_inode_operations = { .symlink = affs_symlink, .mkdir = affs_mkdir, .rmdir = affs_rmdir, - .rename2 = affs_rename, + .rename = affs_rename, .setattr = affs_notify_change, }; diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 381b7d0b6751..51a241e09fbb 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -57,7 +57,7 @@ const struct inode_operations afs_dir_inode_operations = { .symlink = afs_symlink, .mkdir = afs_mkdir, .rmdir = afs_rmdir, - .rename2 = afs_rename, + .rename = afs_rename, .permission = afs_permission, .getattr = afs_getattr, .setattr = afs_setattr, diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 3ba385eaa26e..536d2a387267 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c @@ -133,7 +133,7 @@ static const struct inode_operations bad_inode_ops = .mkdir = bad_inode_mkdir, .rmdir = bad_inode_rmdir, .mknod = bad_inode_mknod, - .rename2 = bad_inode_rename2, + .rename = bad_inode_rename2, .readlink = bad_inode_readlink, /* follow_link must be no-op, otherwise unmounting this inode won't work */ diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 9d5f875e85d0..5e3369f7cd9d 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -274,7 +274,7 @@ const struct inode_operations bfs_dir_inops = { .lookup = bfs_lookup, .link = bfs_link, .unlink = bfs_unlink, - .rename2 = bfs_rename, + .rename = bfs_rename, }; static int bfs_add_entry(struct inode *dir, const unsigned char *name, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e6811c42e41e..c66602091527 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10566,7 +10566,7 @@ static const struct inode_operations btrfs_dir_inode_operations = { .link = btrfs_link, .mkdir = btrfs_mkdir, .rmdir = btrfs_rmdir, - .rename2 = btrfs_rename2, + .rename = btrfs_rename2, .symlink = btrfs_symlink, .setattr = btrfs_setattr, .mknod = btrfs_mknod, diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 02e1507812de..9828850d88de 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c @@ -804,7 +804,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache, !d_backing_inode(subdir)->i_op->lookup || !d_backing_inode(subdir)->i_op->mkdir || !d_backing_inode(subdir)->i_op->create || - !d_backing_inode(subdir)->i_op->rename2 || + !d_backing_inode(subdir)->i_op->rename || !d_backing_inode(subdir)->i_op->rmdir || !d_backing_inode(subdir)->i_op->unlink) goto check_error; diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index cef8252af38a..291a4d59c5f7 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1502,7 +1502,7 @@ const struct inode_operations ceph_dir_iops = { .link = ceph_link, .unlink = ceph_unlink, .rmdir = ceph_unlink, - .rename2 = ceph_rename, + .rename = ceph_rename, .create = ceph_create, .atomic_open = ceph_atomic_open, }; @@ -1513,7 +1513,7 @@ const struct inode_operations ceph_snapdir_iops = { .getattr = ceph_getattr, .mkdir = ceph_mkdir, .rmdir = ceph_unlink, - .rename2 = ceph_rename, + .rename = ceph_rename, }; const struct dentry_operations ceph_dentry_ops = { diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 14ae4b8e1a3c..7d0e0f78da51 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -896,7 +896,7 @@ const struct inode_operations cifs_dir_inode_ops = { .link = cifs_hardlink, .mkdir = cifs_mkdir, .rmdir = cifs_rmdir, - .rename2 = cifs_rename2, + .rename = cifs_rename2, .permission = cifs_permission, .setattr = cifs_setattr, .symlink = cifs_symlink, diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 5d79c26b0484..82aceaef8e4e 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -573,7 +573,7 @@ const struct inode_operations coda_dir_inode_operations = { .mkdir = coda_mkdir, .rmdir = coda_rmdir, .mknod = CODA_EIO_ERROR, - .rename2 = coda_rename, + .rename = coda_rename, .permission = coda_permission, .getattr = coda_getattr, .setattr = coda_setattr, diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index f3ff7c4d384c..fe83c1050048 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -1108,7 +1108,7 @@ const struct inode_operations ecryptfs_dir_iops = { .mkdir = ecryptfs_mkdir, .rmdir = ecryptfs_rmdir, .mknod = ecryptfs_mknod, - .rename2 = ecryptfs_rename, + .rename = ecryptfs_rename, .permission = ecryptfs_permission, .setattr = ecryptfs_setattr, .setxattr = ecryptfs_setxattr, diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index ddf343259f13..53d838200cc9 100644 --- a/fs/exofs/namei.c +++ b/fs/exofs/namei.c @@ -314,7 +314,7 @@ const struct inode_operations exofs_dir_inode_operations = { .mkdir = exofs_mkdir, .rmdir = exofs_rmdir, .mknod = exofs_mknod, - .rename2 = exofs_rename, + .rename = exofs_rename, .setattr = exofs_setattr, }; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 38fac85ff786..be32e20a2b88 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -430,7 +430,7 @@ const struct inode_operations ext2_dir_inode_operations = { .mkdir = ext2_mkdir, .rmdir = ext2_rmdir, .mknod = ext2_mknod, - .rename2 = ext2_rename, + .rename = ext2_rename, #ifdef CONFIG_EXT2_FS_XATTR .setxattr = generic_setxattr, .getxattr = generic_getxattr, diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 34c0142caf6a..0464e2c0d3fd 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3880,7 +3880,7 @@ const struct inode_operations ext4_dir_inode_operations = { .rmdir = ext4_rmdir, .mknod = ext4_mknod, .tmpfile = ext4_tmpfile, - .rename2 = ext4_rename2, + .rename = ext4_rename2, .setattr = ext4_setattr, .setxattr = generic_setxattr, .getxattr = generic_getxattr, diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 73fa356f8fbb..08e3d1d7a500 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -1093,7 +1093,7 @@ const struct inode_operations f2fs_dir_inode_operations = { .mkdir = f2fs_mkdir, .rmdir = f2fs_rmdir, .mknod = f2fs_mknod, - .rename2 = f2fs_rename2, + .rename = f2fs_rename2, .tmpfile = f2fs_tmpfile, .getattr = f2fs_getattr, .setattr = f2fs_setattr, diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 6c814699d5d5..a8f6aa969948 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -637,7 +637,7 @@ static const struct inode_operations msdos_dir_inode_operations = { .unlink = msdos_unlink, .mkdir = msdos_mkdir, .rmdir = msdos_rmdir, - .rename2 = msdos_rename, + .rename = msdos_rename, .setattr = fat_setattr, .getattr = fat_getattr, }; diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index ce8986f3918a..c5e48b8631cc 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -1040,7 +1040,7 @@ static const struct inode_operations vfat_dir_inode_operations = { .unlink = vfat_unlink, .mkdir = vfat_mkdir, .rmdir = vfat_rmdir, - .rename2 = vfat_rename, + .rename = vfat_rename, .setattr = fat_setattr, .getattr = fat_getattr, }; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index c47b7780ce37..4bfeaa70815f 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1876,7 +1876,7 @@ static const struct inode_operations fuse_dir_inode_operations = { .symlink = fuse_symlink, .unlink = fuse_unlink, .rmdir = fuse_rmdir, - .rename2 = fuse_rename2, + .rename = fuse_rename2, .link = fuse_link, .setattr = fuse_setattr, .create = fuse_create, diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index e4da0ecd3285..56825cc8ab87 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -2054,7 +2054,7 @@ const struct inode_operations gfs2_dir_iops = { .mkdir = gfs2_mkdir, .rmdir = gfs2_unlink, .mknod = gfs2_mknod, - .rename2 = gfs2_rename2, + .rename = gfs2_rename2, .permission = gfs2_permission, .setattr = gfs2_setattr, .getattr = gfs2_getattr, diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index d5ce9fcad10f..4f7a1b64e251 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -324,6 +324,6 @@ const struct inode_operations hfs_dir_inode_operations = { .unlink = hfs_remove, .mkdir = hfs_mkdir, .rmdir = hfs_remove, - .rename2 = hfs_rename, + .rename = hfs_rename, .setattr = hfs_inode_setattr, }; diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index ca64a75f12b3..063577958126 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -565,7 +565,7 @@ const struct inode_operations hfsplus_dir_inode_operations = { .rmdir = hfsplus_rmdir, .symlink = hfsplus_symlink, .mknod = hfsplus_mknod, - .rename2 = hfsplus_rename, + .rename = hfsplus_rename, .setxattr = generic_setxattr, .getxattr = generic_getxattr, .listxattr = hfsplus_listxattr, diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 90e46cd752fe..530606169e49 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -885,7 +885,7 @@ static const struct inode_operations hostfs_dir_iops = { .mkdir = hostfs_mkdir, .rmdir = hostfs_rmdir, .mknod = hostfs_mknod, - .rename2 = hostfs_rename2, + .rename = hostfs_rename2, .permission = hostfs_permission, .setattr = hostfs_setattr, }; diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 3c5c1a75569d..f30c14414518 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -622,6 +622,6 @@ const struct inode_operations hpfs_dir_iops = .mkdir = hpfs_mkdir, .rmdir = hpfs_rmdir, .mknod = hpfs_mknod, - .rename2 = hpfs_rename, + .rename = hpfs_rename, .setattr = hpfs_setattr, }; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 50cd7475a942..4ea71eba40a5 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -988,7 +988,7 @@ static const struct inode_operations hugetlbfs_dir_inode_operations = { .mkdir = hugetlbfs_mkdir, .rmdir = simple_rmdir, .mknod = hugetlbfs_mknod, - .rename2 = simple_rename, + .rename = simple_rename, .setattr = hugetlbfs_setattr, }; diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 11e711b12ccf..d957734a2adb 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c @@ -58,7 +58,7 @@ const struct inode_operations jffs2_dir_inode_operations = .mkdir = jffs2_mkdir, .rmdir = jffs2_rmdir, .mknod = jffs2_mknod, - .rename2 = jffs2_rename, + .rename = jffs2_rename, .get_acl = jffs2_get_acl, .set_acl = jffs2_set_acl, .setattr = jffs2_setattr, diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index ee1aa32f7c24..1d88df6ae81b 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -1539,7 +1539,7 @@ const struct inode_operations jfs_dir_inode_operations = { .mkdir = jfs_mkdir, .rmdir = jfs_rmdir, .mknod = jfs_mknod, - .rename2 = jfs_rename, + .rename = jfs_rename, .setxattr = generic_setxattr, .getxattr = generic_getxattr, .listxattr = jfs_listxattr, diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index c7e23ca945ab..390390212b43 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1137,7 +1137,7 @@ const struct inode_operations kernfs_dir_iops = { .mkdir = kernfs_iop_mkdir, .rmdir = kernfs_iop_rmdir, - .rename2 = kernfs_iop_rename, + .rename = kernfs_iop_rename, }; static struct kernfs_node *kernfs_leftmost_descendant(struct kernfs_node *pos) diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 57f2da17a905..be37b907e65a 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c @@ -787,7 +787,7 @@ const struct inode_operations logfs_dir_iops = { .lookup = logfs_lookup, .mkdir = logfs_mkdir, .mknod = logfs_mknod, - .rename2 = logfs_rename, + .rename = logfs_rename, .rmdir = logfs_rmdir, .symlink = logfs_symlink, .unlink = logfs_unlink, diff --git a/fs/minix/namei.c b/fs/minix/namei.c index 6dc210c0e3ce..f7811d508104 100644 --- a/fs/minix/namei.c +++ b/fs/minix/namei.c @@ -268,7 +268,7 @@ const struct inode_operations minix_dir_inode_operations = { .mkdir = minix_mkdir, .rmdir = minix_rmdir, .mknod = minix_mknod, - .rename2 = minix_rename, + .rename = minix_rename, .getattr = minix_getattr, .tmpfile = minix_tmpfile, }; diff --git a/fs/namei.c b/fs/namei.c index 02803bd6cbad..cf3fc8db909c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -4369,7 +4369,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (error) return error; - if (!old_dir->i_op->rename2) + if (!old_dir->i_op->rename) return -EPERM; /* @@ -4425,7 +4425,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (error) goto out; } - error = old_dir->i_op->rename2(old_dir, old_dentry, + error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry, flags); if (error) goto out; diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index a2d3738df4af..6df2a3827574 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -65,7 +65,7 @@ const struct inode_operations ncp_dir_inode_operations = .mkdir = ncp_mkdir, .rmdir = ncp_rmdir, .mknod = ncp_mknod, - .rename2 = ncp_rename, + .rename = ncp_rename, .setattr = ncp_notify_change, }; diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index a85fdae4a51f..698be9361280 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -893,7 +893,7 @@ static const struct inode_operations nfs3_dir_inode_operations = { .mkdir = nfs_mkdir, .rmdir = nfs_rmdir, .mknod = nfs_mknod, - .rename2 = nfs_rename, + .rename = nfs_rename, .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 14956da3cf38..a9dec32ba9ba 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -8937,7 +8937,7 @@ static const struct inode_operations nfs4_dir_inode_operations = { .mkdir = nfs_mkdir, .rmdir = nfs_rmdir, .mknod = nfs_mknod, - .rename2 = nfs_rename, + .rename = nfs_rename, .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 380d0b787983..b7bca8303989 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -685,7 +685,7 @@ static const struct inode_operations nfs_dir_inode_operations = { .mkdir = nfs_mkdir, .rmdir = nfs_rmdir, .mknod = nfs_mknod, - .rename2 = nfs_rename, + .rename = nfs_rename, .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index 8540c13ef374..ea94049c3e79 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c @@ -556,7 +556,7 @@ const struct inode_operations nilfs_dir_inode_operations = { .mkdir = nilfs_mkdir, .rmdir = nilfs_rmdir, .mknod = nilfs_mknod, - .rename2 = nilfs_rename, + .rename = nilfs_rename, .setattr = nilfs_setattr, .permission = nilfs_permission, .fiemap = nilfs_fiemap, diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 1040c10a9493..7fb6a7f023e7 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -2913,7 +2913,7 @@ const struct inode_operations ocfs2_dir_iops = { .symlink = ocfs2_symlink, .mkdir = ocfs2_mkdir, .mknod = ocfs2_mknod, - .rename2 = ocfs2_rename, + .rename = ocfs2_rename, .setattr = ocfs2_setattr, .getattr = ocfs2_getattr, .permission = ocfs2_permission, diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c index 417511bbe362..e81f06be5e7b 100644 --- a/fs/omfs/dir.c +++ b/fs/omfs/dir.c @@ -448,7 +448,7 @@ static int omfs_readdir(struct file *file, struct dir_context *ctx) const struct inode_operations omfs_dir_inops = { .lookup = omfs_lookup, .mkdir = omfs_mkdir, - .rename2 = omfs_rename, + .rename = omfs_rename, .create = omfs_create, .unlink = omfs_remove, .rmdir = omfs_remove, diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index 810d43635dfb..5f015c58bfa2 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c @@ -463,7 +463,7 @@ const struct inode_operations orangefs_dir_inode_operations = { .symlink = orangefs_symlink, .mkdir = orangefs_mkdir, .rmdir = orangefs_unlink, - .rename2 = orangefs_rename, + .rename = orangefs_rename, .setattr = orangefs_setattr, .getattr = orangefs_getattr, .setxattr = generic_setxattr, diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 1560fdc09a5f..480fc7868a2f 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -996,7 +996,7 @@ const struct inode_operations ovl_dir_inode_operations = { .symlink = ovl_symlink, .unlink = ovl_unlink, .rmdir = ovl_rmdir, - .rename2 = ovl_rename2, + .rename = ovl_rename2, .link = ovl_link, .setattr = ovl_setattr, .create = ovl_create, diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 5813ccff8cd9..e218e741cb99 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -114,13 +114,13 @@ static inline int ovl_do_rename(struct inode *olddir, struct dentry *olddentry, { int err; - pr_debug("rename2(%pd2, %pd2, 0x%x)\n", + pr_debug("rename(%pd2, %pd2, 0x%x)\n", olddentry, newdentry, flags); err = vfs_rename(olddir, olddentry, newdir, newdentry, NULL, flags); if (err) { - pr_debug("...rename2(%pd2, %pd2, ...) = %i\n", + pr_debug("...rename(%pd2, %pd2, ...) = %i\n", olddentry, newdentry, err); } return err; diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index c2aa068ff974..1ab6e6c2e60e 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -146,7 +146,7 @@ static const struct inode_operations ramfs_dir_inode_operations = { .mkdir = ramfs_mkdir, .rmdir = simple_rmdir, .mknod = ramfs_mknod, - .rename2 = simple_rename, + .rename = simple_rename, }; static const struct super_operations ramfs_ops = { diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 21b4b7138985..586260ed81c9 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -1652,7 +1652,7 @@ const struct inode_operations reiserfs_dir_inode_operations = { .mkdir = reiserfs_mkdir, .rmdir = reiserfs_rmdir, .mknod = reiserfs_mknod, - .rename2 = reiserfs_rename, + .rename = reiserfs_rename, .setattr = reiserfs_setattr, .setxattr = generic_setxattr, .getxattr = generic_getxattr, diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 765d79de1217..30bf6780985a 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c @@ -289,6 +289,6 @@ const struct inode_operations sysv_dir_inode_operations = { .mkdir = sysv_mkdir, .rmdir = sysv_rmdir, .mknod = sysv_mknod, - .rename2 = sysv_rename, + .rename = sysv_rename, .getattr = sysv_getattr, }; diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 23d1ebabc688..e10e9a00cfc3 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1183,7 +1183,7 @@ const struct inode_operations ubifs_dir_inode_operations = { .mkdir = ubifs_mkdir, .rmdir = ubifs_rmdir, .mknod = ubifs_mknod, - .rename2 = ubifs_rename, + .rename = ubifs_rename, .setattr = ubifs_setattr, .getattr = ubifs_getattr, .setxattr = generic_setxattr, diff --git a/fs/udf/namei.c b/fs/udf/namei.c index ca2ec0061802..17e9d4af3010 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -1357,6 +1357,6 @@ const struct inode_operations udf_dir_inode_operations = { .mkdir = udf_mkdir, .rmdir = udf_rmdir, .mknod = udf_mknod, - .rename2 = udf_rename, + .rename = udf_rename, .tmpfile = udf_tmpfile, }; diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 719c9c9b83d8..f2f11c382b6d 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -337,5 +337,5 @@ const struct inode_operations ufs_dir_inode_operations = { .mkdir = ufs_mkdir, .rmdir = ufs_rmdir, .mknod = ufs_mknod, - .rename2 = ufs_rename, + .rename = ufs_rename, }; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index b24c3102fa93..a66c781e5468 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -1059,7 +1059,7 @@ static const struct inode_operations xfs_dir_inode_operations = { */ .rmdir = xfs_vn_unlink, .mknod = xfs_vn_mknod, - .rename2 = xfs_vn_rename, + .rename = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, .getattr = xfs_vn_getattr, @@ -1087,7 +1087,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { */ .rmdir = xfs_vn_unlink, .mknod = xfs_vn_mknod, - .rename2 = xfs_vn_rename, + .rename = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, .getattr = xfs_vn_getattr, diff --git a/include/linux/fs.h b/include/linux/fs.h index 6b14ceba4f20..cf7e621f7413 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1732,7 +1732,7 @@ struct inode_operations { int (*mkdir) (struct inode *,struct dentry *,umode_t); int (*rmdir) (struct inode *,struct dentry *); int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t); - int (*rename2) (struct inode *, struct dentry *, + int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *, unsigned int); int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index c92fd8936d33..5967b870a895 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c @@ -189,7 +189,7 @@ static const struct inode_operations bpf_dir_iops = { .mknod = bpf_mkobj, .mkdir = bpf_mkdir, .rmdir = simple_rmdir, - .rename2 = simple_rename, + .rename = simple_rename, .link = simple_link, .unlink = simple_unlink, }; diff --git a/mm/shmem.c b/mm/shmem.c index 971fc83e6402..efbef2336605 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3814,7 +3814,7 @@ static const struct inode_operations shmem_dir_inode_operations = { .mkdir = shmem_mkdir, .rmdir = shmem_rmdir, .mknod = shmem_mknod, - .rename2 = shmem_rename2, + .rename = shmem_rename2, .tmpfile = shmem_tmpfile, #endif #ifdef CONFIG_TMPFS_XATTR diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 38bcdbc06bb2..a97b275ca3af 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c @@ -173,7 +173,7 @@ static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer, * Use filesystem name if filesystem does not support rename() * operation. */ - if (!inode->i_op->rename2) + if (!inode->i_op->rename) goto prepend_filesystem_name; } /* Prepend device name. */ @@ -283,7 +283,7 @@ char *tomoyo_realpath_from_path(const struct path *path) * or dentry without vfsmount. */ if (!path->mnt || - (!inode->i_op->rename2)) + (!inode->i_op->rename)) pos = tomoyo_get_local_path(path->dentry, buf, buf_len - 1); /* Get absolute name for the rest. */ -- cgit v1.2.3