Commit d27fb65b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull misc dcache updates from Al Viro:
 "Most of this pile is putting name length into struct name_snapshot and
  making use of it.

  The beginning of this series ("ovl_lookup_real_one(): don't bother
  with strlen()") ought to have been split in two (separate switch of
  name_snapshot to struct qstr from overlayfs reaping the trivial
  benefits of that), but I wanted to avoid a rebase - by the time I'd
  spotted that it was (a) in -next and (b) close to 5.1-final ;-/"

* 'work.dcache' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  audit_compare_dname_path(): switch to const struct qstr *
  audit_update_watch(): switch to const struct qstr *
  inotify_handle_event(): don't bother with strlen()
  fsnotify: switch send_to_group() and ->handle_event to const struct qstr *
  fsnotify(): switch to passing const struct qstr * for file_name
  switch fsnotify_move() to passing const struct qstr * for old_name
  ovl_lookup_real_one(): don't bother with strlen()
  sysv: bury the broken "quietly truncate the long filenames" logics
  nsfs: unobfuscate
  unexport d_alloc_pseudo()
parents d3511f53 795d673a
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -668,3 +668,8 @@ in your dentry operations instead.
	DCACHE_RCUACCESS is gone; having an RCU delay on dentry freeing is the
	DCACHE_RCUACCESS is gone; having an RCU delay on dentry freeing is the
	default.  DCACHE_NORCU opts out, and only d_alloc_pseudo() has any
	default.  DCACHE_NORCU opts out, and only d_alloc_pseudo() has any
	business doing so.
	business doing so.
--
[mandatory]
	d_alloc_pseudo() is internal-only; uses outside of alloc_file_pseudo() are
	very suspect (and won't work in modules).  Such uses are very likely to
	be misspelled d_alloc_anon().
+9 −9
Original line number Original line Diff line number Diff line
@@ -284,25 +284,23 @@ static inline int dname_external(const struct dentry *dentry)
void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry)
void take_dentry_name_snapshot(struct name_snapshot *name, struct dentry *dentry)
{
{
	spin_lock(&dentry->d_lock);
	spin_lock(&dentry->d_lock);
	name->name = dentry->d_name;
	if (unlikely(dname_external(dentry))) {
	if (unlikely(dname_external(dentry))) {
		struct external_name *p = external_name(dentry);
		atomic_inc(&external_name(dentry)->u.count);
		atomic_inc(&p->u.count);
		spin_unlock(&dentry->d_lock);
		name->name = p->name;
	} else {
	} else {
		memcpy(name->inline_name, dentry->d_iname,
		memcpy(name->inline_name, dentry->d_iname,
		       dentry->d_name.len + 1);
		       dentry->d_name.len + 1);
		spin_unlock(&dentry->d_lock);
		name->name.name = name->inline_name;
		name->name = name->inline_name;
	}
	}
	spin_unlock(&dentry->d_lock);
}
}
EXPORT_SYMBOL(take_dentry_name_snapshot);
EXPORT_SYMBOL(take_dentry_name_snapshot);


void release_dentry_name_snapshot(struct name_snapshot *name)
void release_dentry_name_snapshot(struct name_snapshot *name)
{
{
	if (unlikely(name->name != name->inline_name)) {
	if (unlikely(name->name.name != name->inline_name)) {
		struct external_name *p;
		struct external_name *p;
		p = container_of(name->name, struct external_name, name[0]);
		p = container_of(name->name.name, struct external_name, name[0]);
		if (unlikely(atomic_dec_and_test(&p->u.count)))
		if (unlikely(atomic_dec_and_test(&p->u.count)))
			kfree_rcu(p, u.head);
			kfree_rcu(p, u.head);
	}
	}
@@ -1742,6 +1740,9 @@ struct dentry *d_alloc_cursor(struct dentry * parent)
 * never be anyone's children or parents.  Unlike all other
 * never be anyone's children or parents.  Unlike all other
 * dentries, these will not have RCU delay between dropping the
 * dentries, these will not have RCU delay between dropping the
 * last reference and freeing them.
 * last reference and freeing them.
 *
 * The only user is alloc_file_pseudo() and that's what should
 * be considered a public interface.  Don't use directly.
 */
 */
struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name)
struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name)
{
{
@@ -1750,7 +1751,6 @@ struct dentry *d_alloc_pseudo(struct super_block *sb, const struct qstr *name)
		dentry->d_flags |= DCACHE_NORCU;
		dentry->d_flags |= DCACHE_NORCU;
	return dentry;
	return dentry;
}
}
EXPORT_SYMBOL(d_alloc_pseudo);


struct dentry *d_alloc_name(struct dentry *parent, const char *name)
struct dentry *d_alloc_name(struct dentry *parent, const char *name)
{
{
+1 −1
Original line number Original line Diff line number Diff line
@@ -818,7 +818,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
		goto exit;
		goto exit;
	}
	}
	d_move(old_dentry, dentry);
	d_move(old_dentry, dentry);
	fsnotify_move(d_inode(old_dir), d_inode(new_dir), old_name.name,
	fsnotify_move(d_inode(old_dir), d_inode(new_dir), &old_name.name,
		d_is_dir(old_dentry),
		d_is_dir(old_dentry),
		NULL, old_dentry);
		NULL, old_dentry);
	release_dentry_name_snapshot(&old_name);
	release_dentry_name_snapshot(&old_name);
+1 −0
Original line number Original line Diff line number Diff line
@@ -155,6 +155,7 @@ extern struct dentry *__d_alloc(struct super_block *, const struct qstr *);
extern int d_set_mounted(struct dentry *dentry);
extern int d_set_mounted(struct dentry *dentry);
extern long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc);
extern long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc);
extern struct dentry *d_alloc_cursor(struct dentry *);
extern struct dentry *d_alloc_cursor(struct dentry *);
extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *);


/*
/*
 * read_write.c
 * read_write.c
+4 −2
Original line number Original line Diff line number Diff line
@@ -885,6 +885,7 @@ repeat:
	list_for_each_entry(info, &kernfs_root(kn)->supers, node) {
	list_for_each_entry(info, &kernfs_root(kn)->supers, node) {
		struct kernfs_node *parent;
		struct kernfs_node *parent;
		struct inode *inode;
		struct inode *inode;
		struct qstr name;


		/*
		/*
		 * We want fsnotify_modify() on @kn but as the
		 * We want fsnotify_modify() on @kn but as the
@@ -896,6 +897,7 @@ repeat:
		if (!inode)
		if (!inode)
			continue;
			continue;


		name = (struct qstr)QSTR_INIT(kn->name, strlen(kn->name));
		parent = kernfs_get_parent(kn);
		parent = kernfs_get_parent(kn);
		if (parent) {
		if (parent) {
			struct inode *p_inode;
			struct inode *p_inode;
@@ -903,7 +905,7 @@ repeat:
			p_inode = ilookup(info->sb, parent->id.ino);
			p_inode = ilookup(info->sb, parent->id.ino);
			if (p_inode) {
			if (p_inode) {
				fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD,
				fsnotify(p_inode, FS_MODIFY | FS_EVENT_ON_CHILD,
					 inode, FSNOTIFY_EVENT_INODE, kn->name, 0);
					 inode, FSNOTIFY_EVENT_INODE, &name, 0);
				iput(p_inode);
				iput(p_inode);
			}
			}


@@ -911,7 +913,7 @@ repeat:
		}
		}


		fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE,
		fsnotify(inode, FS_MODIFY, inode, FSNOTIFY_EVENT_INODE,
			 kn->name, 0);
			 &name, 0);
		iput(inode);
		iput(inode);
	}
	}


Loading