Skip to content

Commit 58ed4e7

Browse files
Andreas GruenbacherMiklos Szeredi
authored andcommitted
ovl: store ovl_entry in inode->i_private for all inodes
Previously this was only done for directory inodes. Doing so for all inodes makes for a nice cleanup in ovl_permission at zero cost. Inodes are not shared for hard links on the overlay, so this works fine. Signed-off-by: Miklos Szeredi <[email protected]>
1 parent eead4f2 commit 58ed4e7

File tree

1 file changed

+11
-37
lines changed

1 file changed

+11
-37
lines changed

fs/overlayfs/inode.c

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -109,31 +109,12 @@ static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry,
109109

110110
int ovl_permission(struct inode *inode, int mask)
111111
{
112-
struct ovl_entry *oe;
113-
struct dentry *alias = NULL;
114-
struct inode *realinode;
115-
struct dentry *realdentry;
112+
struct ovl_entry *oe = inode->i_private;
116113
bool is_upper;
114+
struct dentry *realdentry = ovl_entry_real(oe, &is_upper);
115+
struct inode *realinode;
117116
int err;
118117

119-
if (S_ISDIR(inode->i_mode)) {
120-
oe = inode->i_private;
121-
} else if (mask & MAY_NOT_BLOCK) {
122-
return -ECHILD;
123-
} else {
124-
/*
125-
* For non-directories find an alias and get the info
126-
* from there.
127-
*/
128-
alias = d_find_any_alias(inode);
129-
if (WARN_ON(!alias))
130-
return -ENOENT;
131-
132-
oe = alias->d_fsdata;
133-
}
134-
135-
realdentry = ovl_entry_real(oe, &is_upper);
136-
137118
if (ovl_is_default_permissions(inode)) {
138119
struct kstat stat;
139120
struct path realpath = { .dentry = realdentry };
@@ -145,26 +126,23 @@ int ovl_permission(struct inode *inode, int mask)
145126

146127
err = vfs_getattr(&realpath, &stat);
147128
if (err)
148-
goto out_dput;
129+
return err;
149130

150-
err = -ESTALE;
151131
if ((stat.mode ^ inode->i_mode) & S_IFMT)
152-
goto out_dput;
132+
return -ESTALE;
153133

154134
inode->i_mode = stat.mode;
155135
inode->i_uid = stat.uid;
156136
inode->i_gid = stat.gid;
157137

158-
err = generic_permission(inode, mask);
159-
goto out_dput;
138+
return generic_permission(inode, mask);
160139
}
161140

162141
/* Careful in RCU walk mode */
163-
realinode = ACCESS_ONCE(realdentry->d_inode);
142+
realinode = d_inode_rcu(realdentry);
164143
if (!realinode) {
165144
WARN_ON(!(mask & MAY_NOT_BLOCK));
166-
err = -ENOENT;
167-
goto out_dput;
145+
return -ENOENT;
168146
}
169147

170148
if (mask & MAY_WRITE) {
@@ -183,16 +161,12 @@ int ovl_permission(struct inode *inode, int mask)
183161
* constructed return EROFS to prevent modification of
184162
* upper layer.
185163
*/
186-
err = -EROFS;
187164
if (is_upper && !IS_RDONLY(inode) && IS_RDONLY(realinode) &&
188165
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
189-
goto out_dput;
166+
return -EROFS;
190167
}
191168

192-
err = __inode_permission(realinode, mask);
193-
out_dput:
194-
dput(alias);
195-
return err;
169+
return __inode_permission(realinode, mask);
196170
}
197171

198172
static const char *ovl_get_link(struct dentry *dentry,
@@ -405,11 +379,11 @@ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
405379
inode->i_ino = get_next_ino();
406380
inode->i_mode = mode;
407381
inode->i_flags |= S_NOATIME | S_NOCMTIME;
382+
inode->i_private = oe;
408383

409384
mode &= S_IFMT;
410385
switch (mode) {
411386
case S_IFDIR:
412-
inode->i_private = oe;
413387
inode->i_op = &ovl_dir_inode_operations;
414388
inode->i_fop = &ovl_dir_operations;
415389
break;

0 commit comments

Comments
 (0)