Think of this as a sequel to my post about a year ago.
The following peice of code is from Unionfs’s copyup_permission(). It is (or should be) a simple function that is supposed to copy the permissions from one inode to another. Well, I can’t help but remember this one slide from Greg Kroah-Hartman’s keynote this year at Ottawa Linux Symposium. Here’s the slide:
The quote definitely applies to copyup_permission(). It seems very clear that it “evolved” to something very odd. Anyway, I shall torment you no longer, here is the code:
static int copyup_permissions(struct super_block *sb,
struct dentry *old_hidden_dentry,
struct dentry *new_hidden_dentry)
{
struct iattr newattrs;
int err;
print_entry_location();
newattrs.ia_atime = old_hidden_dentry->d_inode->i_atime;
newattrs.ia_mtime = old_hidden_dentry->d_inode->i_mtime;
newattrs.ia_ctime = old_hidden_dentry->d_inode->i_ctime;
newattrs.ia_valid = ATTR_CTIME | ATTR_ATIME | ATTR_MTIME |
ATTR_ATIME_SET | ATTR_MTIME_SET;
/* original mode of old file */
newattrs.ia_mode = old_hidden_dentry->d_inode->i_mode;
newattrs.ia_gid = old_hidden_dentry->d_inode->i_gid;
newattrs.ia_uid = old_hidden_dentry->d_inode->i_uid;
newattrs.ia_valid |= ATTR_FORCE | ATTR_GID | ATTR_UID | ATTR_MODE;
if (newattrs.ia_valid & ATTR_MODE) {
newattrs.ia_mode = (newattrs.ia_mode & S_IALLUGO) |
(old_hidden_dentry->d_inode->i_mode & ~S_IALLUGO);
}
err = notify_change(new_hidden_dentry, &newattrs);
print_exit_status(err);
return err;
}
It was actually Seth Arnold that noticed that the condition will ALWAYS be true because ATTR_MODE is set in the line just above it. Furthermore, if one eliminates the if statement and replaces newattr.ia_mode in the assignment with what it is set to just few lines before (right after the comment) he gets:
newattrs.ia_mode = (old_hidden_dentry->d_inode->i_mode & S_IALLUGO) |
(old_hidden_dentry->d_inode->i_mode & ~S_IALLUGO);
If you are up to speed with bitwise operations, you’ll realize that it can be simplified to:
newattrs.ia_mode = old_hidden_dentry->d_inode->i_mode;
Brilliant!