linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Al Viro <viro@zeniv.linux.org.uk>
Subject: [PATCH 3.18 32/50] dentry name snapshots
Date: Fri,  4 Aug 2017 16:16:18 -0700	[thread overview]
Message-ID: <20170804231552.949516993@linuxfoundation.org> (raw)
In-Reply-To: <20170804231550.830518786@linuxfoundation.org>

3.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Al Viro <viro@zeniv.linux.org.uk>

commit 49d31c2f389acfe83417083e1208422b4091cd9e upstream.

take_dentry_name_snapshot() takes a safe snapshot of dentry name;
if the name is a short one, it gets copied into caller-supplied
structure, otherwise an extra reference to external name is grabbed
(those are never modified).  In either case the pointer to stable
string is stored into the same structure.

dentry must be held by the caller of take_dentry_name_snapshot(),
but may be freely dropped afterwards - the snapshot will stay
until destroyed by release_dentry_name_snapshot().

Intended use:
	struct name_snapshot s;

	take_dentry_name_snapshot(&s, dentry);
	...
	access s.name
	...
	release_dentry_name_snapshot(&s);

Replaces fsnotify_oldname_...(), gets used in fsnotify to obtain the name
to pass down with event.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 fs/dcache.c              |   27 +++++++++++++++++++++++++++
 fs/debugfs/inode.c       |   10 +++++-----
 fs/namei.c               |    8 ++++----
 fs/notify/fsnotify.c     |    8 ++++++--
 include/linux/dcache.h   |    7 +++++++
 include/linux/fsnotify.h |   31 -------------------------------
 6 files changed, 49 insertions(+), 42 deletions(-)

--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -3549,3 +3549,30 @@ void __init vfs_caches_init(unsigned lon
 	bdev_cache_init();
 	chrdev_init();
 }
+
+void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry)
+{
+	spin_lock(&dentry->d_lock);
+	if (unlikely(dname_external(dentry))) {
+		struct external_name *p = external_name(dentry);
+		atomic_inc(&p->u.count);
+		spin_unlock(&dentry->d_lock);
+		name->name = p->name;
+	} else {
+		memcpy(name->inline_name, dentry->d_iname, DNAME_INLINE_LEN);
+		spin_unlock(&dentry->d_lock);
+		name->name = name->inline_name;
+	}
+}
+EXPORT_SYMBOL(take_dentry_name_snapshot);
+
+void release_dentry_name_snapshot(struct name_snapshot *name)
+{
+	if (unlikely(name->name != name->inline_name)) {
+		struct external_name *p;
+		p = container_of(name->name, struct external_name, name[0]);
+		if (unlikely(atomic_dec_and_test(&p->u.count)))
+			kfree_rcu(p, u.head);
+	}
+}
+EXPORT_SYMBOL(release_dentry_name_snapshot);
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -620,7 +620,7 @@ struct dentry *debugfs_rename(struct den
 {
 	int error;
 	struct dentry *dentry = NULL, *trap;
-	const char *old_name;
+	struct name_snapshot old_name;
 
 	trap = lock_rename(new_dir, old_dir);
 	/* Source or destination directories don't exist? */
@@ -635,19 +635,19 @@ struct dentry *debugfs_rename(struct den
 	if (IS_ERR(dentry) || dentry == trap || dentry->d_inode)
 		goto exit;
 
-	old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+	take_dentry_name_snapshot(&old_name, old_dentry);
 
 	error = simple_rename(old_dir->d_inode, old_dentry, new_dir->d_inode,
 		dentry);
 	if (error) {
-		fsnotify_oldname_free(old_name);
+		release_dentry_name_snapshot(&old_name);
 		goto exit;
 	}
 	d_move(old_dentry, dentry);
-	fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
+	fsnotify_move(d_inode(old_dir), d_inode(new_dir), old_name.name,
 		S_ISDIR(old_dentry->d_inode->i_mode),
 		NULL, old_dentry);
-	fsnotify_oldname_free(old_name);
+	release_dentry_name_snapshot(&old_name);
 	unlock_rename(new_dir, old_dir);
 	dput(dentry);
 	return old_dentry;
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -4088,11 +4088,11 @@ int vfs_rename(struct inode *old_dir, st
 {
 	int error;
 	bool is_dir = d_is_dir(old_dentry);
-	const unsigned char *old_name;
 	struct inode *source = old_dentry->d_inode;
 	struct inode *target = new_dentry->d_inode;
 	bool new_is_dir = false;
 	unsigned max_links = new_dir->i_sb->s_max_links;
+	struct name_snapshot old_name;
 
 	if (source == target)
 		return 0;
@@ -4142,7 +4142,7 @@ int vfs_rename(struct inode *old_dir, st
 	if (error)
 		return error;
 
-	old_name = fsnotify_oldname_init(old_dentry->d_name.name);
+	take_dentry_name_snapshot(&old_name, old_dentry);
 	dget(new_dentry);
 	if (!is_dir || (flags & RENAME_EXCHANGE))
 		lock_two_nondirectories(source, target);
@@ -4203,14 +4203,14 @@ out:
 		mutex_unlock(&target->i_mutex);
 	dput(new_dentry);
 	if (!error) {
-		fsnotify_move(old_dir, new_dir, old_name, is_dir,
+		fsnotify_move(old_dir, new_dir, old_name.name, is_dir,
 			      !(flags & RENAME_EXCHANGE) ? target : NULL, old_dentry);
 		if (flags & RENAME_EXCHANGE) {
 			fsnotify_move(new_dir, old_dir, old_dentry->d_name.name,
 				      new_is_dir, NULL, new_dentry);
 		}
 	}
-	fsnotify_oldname_free(old_name);
+	release_dentry_name_snapshot(&old_name);
 
 	return error;
 }
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -105,16 +105,20 @@ int __fsnotify_parent(struct path *path,
 	if (unlikely(!fsnotify_inode_watches_children(p_inode)))
 		__fsnotify_update_child_dentry_flags(p_inode);
 	else if (p_inode->i_fsnotify_mask & mask) {
+		struct name_snapshot name;
+
 		/* we are notifying a parent so come up with the new mask which
 		 * specifies these are events which came from a child. */
 		mask |= FS_EVENT_ON_CHILD;
 
+		take_dentry_name_snapshot(&name, dentry);
 		if (path)
 			ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH,
-				       dentry->d_name.name, 0);
+				       name.name, 0);
 		else
 			ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
-				       dentry->d_name.name, 0);
+				       name.name, 0);
+		release_dentry_name_snapshot(&name);
 	}
 
 	dput(parent);
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -527,4 +527,11 @@ static inline struct dentry *d_backing_d
 	return upper;
 }
 
+struct name_snapshot {
+	const char *name;
+	char inline_name[DNAME_INLINE_LEN];
+};
+void take_dentry_name_snapshot(struct name_snapshot *, struct dentry *);
+void release_dentry_name_snapshot(struct name_snapshot *);
+
 #endif	/* __LINUX_DCACHE_H */
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -310,35 +310,4 @@ static inline void fsnotify_change(struc
 	}
 }
 
-#if defined(CONFIG_FSNOTIFY)	/* notify helpers */
-
-/*
- * fsnotify_oldname_init - save off the old filename before we change it
- */
-static inline const unsigned char *fsnotify_oldname_init(const unsigned char *name)
-{
-	return kstrdup(name, GFP_KERNEL);
-}
-
-/*
- * fsnotify_oldname_free - free the name we got from fsnotify_oldname_init
- */
-static inline void fsnotify_oldname_free(const unsigned char *old_name)
-{
-	kfree(old_name);
-}
-
-#else	/* CONFIG_FSNOTIFY */
-
-static inline const char *fsnotify_oldname_init(const unsigned char *name)
-{
-	return NULL;
-}
-
-static inline void fsnotify_oldname_free(const unsigned char *old_name)
-{
-}
-
-#endif	/*  CONFIG_FSNOTIFY */
-
 #endif	/* _LINUX_FS_NOTIFY_H */

  parent reply	other threads:[~2017-08-04 23:34 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-04 23:15 [PATCH 3.18 00/50] 3.18.64-stable review Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 01/50] af_key: Add lock to key dump Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 02/50] pstore: Make spinlock per zone instead of global Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 03/50] net: reduce skb_warn_bad_offload() noise Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 04/50] powerpc/pseries: Fix of_node_put() underflow during reconfig remove Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 05/50] md/raid5: add thread_group worker async_tx_issue_pending_all Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 06/50] drm/vmwgfx: Fix gcc-7.1.1 warning Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 07/50] KVM: PPC: Book3S HV: Restore critical SPRs to host values on guest exit Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 08/50] KVM: PPC: Book3S HV: Reload HTM registers explicitly Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 09/50] KVM: PPC: Book3S HV: Save/restore host values of debug registers Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 10/50] Revert "powerpc/numa: Fix percpu allocations to be NUMA aware" Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 11/50] Staging: comedi: comedi_fops: Avoid orphaned proc entry Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 12/50] Bluetooth: bnep: bnep_add_connection() should verify that its dealing with l2cap socket Greg Kroah-Hartman
2017-08-04 23:15 ` [PATCH 3.18 13/50] Bluetooth: Fix potential NULL dereference Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 14/50] Bluetooth: cmtp: cmtp_add_connection() should verify that its dealing with l2cap socket Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 15/50] net: phy: Do not perform software reset for Generic PHY Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 16/50] isdn: Fix a sleep-in-atomic bug Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 17/50] string: provide strscpy() Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 18/50] strscpy: zero any trailing garbage bytes in the destination Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 19/50] isdn/i4l: fix buffer overflow Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 20/50] wil6210: fix deadlock when using fw_no_recovery option Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 21/50] mailbox: always wait in mbox_send_message for blocking Tx mode Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 22/50] mailbox: skip complete wait event if timer expired Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 23/50] mailbox: handle empty message in tx_tick Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 24/50] mpt3sas: Dont overreach ioc->reply_post[] during initialization Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 25/50] kaweth: fix firmware download Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 26/50] kaweth: fix oops upon failed memory allocation Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 27/50] ipv6: fix possible deadlock in ip6_fl_purge / ip6_fl_gc Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 28/50] net: sctp: fix race for one-to-many sockets in sendmsgs auto associate Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 29/50] sh_eth: Fix ethtool operation crash when net device is down Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 30/50] net, sched: fix soft lockup in tc_classify Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 31/50] ipmi/watchdog: fix watchdog timeout set on reboot Greg Kroah-Hartman
2017-08-04 23:16 ` Greg Kroah-Hartman [this message]
2017-08-04 23:16 ` [PATCH 3.18 33/50] [media] v4l: s5c73m3: fix negation operator Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 34/50] pstore: Allow prz to control need for locking Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 35/50] pstore: Correctly initialize spinlock and flags Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 36/50] pstore: Use dynamic spinlock initializer Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 37/50] net: skb_needs_check() accepts CHECKSUM_NONE for tx Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 38/50] tpm: fix a kernel memory leak in tpm-sysfs.c Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 39/50] x86/mce/AMD: Make the init code more robust Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 40/50] r8169: add support for RTL8168 series add-on card Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 42/50] ipv6: Should use consistent conditional judgement for ip6 fragment between __ip6_append_data and ip6_finish_output Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 43/50] net/mlx4: Remove BUG_ON from ICM allocation routine Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 44/50] drm/msm: Ensure that the hardware write pointer is valid Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 45/50] drm/msm: Verify that MSM_SUBMIT_BO_FLAGS are set Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 46/50] vfio-pci: use 32-bit comparisons for register address for gcc-4.5 Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 47/50] ASoC: tlv320aic3x: Mark the RESET register as volatile Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 48/50] spi: dw: Make debugfs name unique between instances Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 49/50] vlan: Propagate MAC address to VLANs Greg Kroah-Hartman
2017-08-04 23:16 ` [PATCH 3.18 50/50] xfrm: Dont use sk_family for socket policy lookups Greg Kroah-Hartman
2017-08-05  1:43 ` [PATCH 3.18 00/50] 3.18.64-stable review Guenter Roeck
2017-08-05  2:46   ` Greg Kroah-Hartman
2017-08-05  2:51     ` Greg Kroah-Hartman
2017-08-05  3:00       ` Greg Kroah-Hartman
2017-08-05  4:01         ` Guenter Roeck
2017-08-05 15:43           ` Greg Kroah-Hartman
2017-08-05  5:55       ` Willy Tarreau
2017-08-05  6:02         ` Willy Tarreau
2017-08-05 15:43           ` Greg Kroah-Hartman
2017-08-05 19:11             ` Guenter Roeck
2017-08-07 19:34               ` Greg Kroah-Hartman
2017-08-08  4:11                 ` Guenter Roeck
2017-08-05  3:57     ` Guenter Roeck
2017-08-05 15:45       ` Greg Kroah-Hartman
2017-08-05  1:52 ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170804231552.949516993@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).