Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e36cb0b8 authored by David Howells's avatar David Howells Committed by Al Viro
Browse files

VFS: (Scripted) Convert S_ISLNK/DIR/REG(dentry->d_inode) to d_is_*(dentry)



Convert the following where appropriate:

 (1) S_ISLNK(dentry->d_inode) to d_is_symlink(dentry).

 (2) S_ISREG(dentry->d_inode) to d_is_reg(dentry).

 (3) S_ISDIR(dentry->d_inode) to d_is_dir(dentry).  This is actually more
     complicated than it appears as some calls should be converted to
     d_can_lookup() instead.  The difference is whether the directory in
     question is a real dir with a ->lookup op or whether it's a fake dir with
     a ->d_automount op.

In some circumstances, we can subsume checks for dentry->d_inode not being
NULL into this, provided we the code isn't in a filesystem that expects
d_inode to be NULL if the dirent really *is* negative (ie. if we're going to
use d_inode() rather than d_backing_inode() to get the inode pointer).

Note that the dentry type field may be set to something other than
DCACHE_MISS_TYPE when d_inode is NULL in the case of unionmount, where the VFS
manages the fall-through from a negative dentry to a lower layer.  In such a
case, the dentry type of the negative union dentry is set to the same as the
type of the lower dentry.

However, if you know d_inode is not NULL at the call site, then you can use
the d_is_xxx() functions even in a filesystem.

There is one further complication: a 0,0 chardev dentry may be labelled
DCACHE_WHITEOUT_TYPE rather than DCACHE_SPECIAL_TYPE.  Strictly, this was
intended for special directory entry types that don't have attached inodes.

The following perl+coccinelle script was used:

use strict;

my @callers;
open($fd, 'git grep -l \'S_IS[A-Z].*->d_inode\' |') ||
    die "Can't grep for S_ISDIR and co. callers";
@callers = <$fd>;
close($fd);
unless (@callers) {
    print "No matches\n";
    exit(0);
}

my @cocci = (
    '@@',
    'expression E;',
    '@@',
    '',
    '- S_ISLNK(E->d_inode->i_mode)',
    '+ d_is_symlink(E)',
    '',
    '@@',
    'expression E;',
    '@@',
    '',
    '- S_ISDIR(E->d_inode->i_mode)',
    '+ d_is_dir(E)',
    '',
    '@@',
    'expression E;',
    '@@',
    '',
    '- S_ISREG(E->d_inode->i_mode)',
    '+ d_is_reg(E)' );

my $coccifile = "tmp.sp.cocci";
open($fd, ">$coccifile") || die $coccifile;
print($fd "$_\n") || die $coccifile foreach (@cocci);
close($fd);

foreach my $file (@callers) {
    chomp $file;
    print "Processing ", $file, "\n";
    system("spatch", "--sp-file", $coccifile, $file, "--in-place", "--no-show-diff") == 0 ||
	die "spatch failed";
}

[AV: overlayfs parts skipped]

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2c616d4d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ static void hypfs_remove(struct dentry *dentry)
	parent = dentry->d_parent;
	mutex_lock(&parent->d_inode->i_mutex);
	if (hypfs_positive(dentry)) {
		if (S_ISDIR(dentry->d_inode->i_mode))
		if (d_is_dir(dentry))
			simple_rmdir(parent->d_inode, dentry);
		else
			simple_unlink(parent->d_inode, dentry);
+1 −1
Original line number Diff line number Diff line
@@ -1127,7 +1127,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
	}

	/* Write all dirty data */
	if (S_ISREG(dentry->d_inode->i_mode))
	if (d_is_reg(dentry))
		filemap_write_and_wait(dentry->d_inode->i_mapping);

	retval = p9_client_wstat(fid, &wstat);
+1 −1
Original line number Diff line number Diff line
@@ -374,7 +374,7 @@ static struct dentry *should_expire(struct dentry *dentry,
		return NULL;
	}

	if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
	if (dentry->d_inode && d_is_symlink(dentry)) {
		DPRINTK("checking symlink %p %pd", dentry, dentry);
		/*
		 * A symlink can't be "busy" in the usual sense so
+2 −2
Original line number Diff line number Diff line
@@ -371,7 +371,7 @@ static struct vfsmount *autofs4_d_automount(struct path *path)
	 * having d_mountpoint() true, so there's no need to call back
	 * to the daemon.
	 */
	if (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)) {
	if (dentry->d_inode && d_is_symlink(dentry)) {
		spin_unlock(&sbi->fs_lock);
		goto done;
	}
@@ -485,7 +485,7 @@ static int autofs4_d_manage(struct dentry *dentry, bool rcu_walk)
		 * an incorrect ELOOP error return.
		 */
		if ((!d_mountpoint(dentry) && !simple_empty(dentry)) ||
		    (dentry->d_inode && S_ISLNK(dentry->d_inode->i_mode)))
		    (dentry->d_inode && d_is_symlink(dentry)))
			status = -EISDIR;
	}
	spin_unlock(&sbi->fs_lock);
+2 −2
Original line number Diff line number Diff line
@@ -776,11 +776,11 @@ static int btrfs_may_delete(struct inode *dir, struct dentry *victim, int isdir)
	    IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode))
		return -EPERM;
	if (isdir) {
		if (!S_ISDIR(victim->d_inode->i_mode))
		if (!d_is_dir(victim))
			return -ENOTDIR;
		if (IS_ROOT(victim))
			return -EBUSY;
	} else if (S_ISDIR(victim->d_inode->i_mode))
	} else if (d_is_dir(victim))
		return -EISDIR;
	if (IS_DEADDIR(dir))
		return -ENOENT;
Loading