Skip to content

Commit db3d841

Browse files
committed
fs/pidfs: make 'lsof' happy with our inode changes
pidfs started using much saner inodes in commit b28ddcc ("pidfs: convert to path_from_stashed() helper"), but that exposed the fact that lsof had some knowledge of just how odd our old anon_inode usage was. For example, legacy anon_inodes hadn't even initialized the inode type in the inode mode, so everything had a type of zero. So sane tools like 'stat' would report these files as "weird file", but 'lsof' instead used that (together with the name of the link in proc) to notice that it's an anonymous inode, and used it to detect pidfd files. Let's keep our internal new sane inode model, but mask the file type bits at 'stat()' time in the getattr() function we already have, and by making the dentry name match what lsof expects too. This keeps our internal models sane, but should make user space see the same old odd behavior. Reported-by: Jiri Slaby <[email protected]> Link: https://lore.kernel.org/all/[email protected]/ Link: lsof-org/lsof#317 Cc: Alexander Viro <[email protected]> Cc: Seth Forshee <[email protected]> Cc: Tycho Andersen <[email protected]> Signed-off-by: Christian Brauner <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 8f6a15f commit db3d841

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

fs/pidfs.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,32 @@ static int pidfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
169169
return -EOPNOTSUPP;
170170
}
171171

172+
173+
/*
174+
* User space expects pidfs inodes to have no file type in st_mode.
175+
*
176+
* In particular, 'lsof' has this legacy logic:
177+
*
178+
* type = s->st_mode & S_IFMT;
179+
* switch (type) {
180+
* ...
181+
* case 0:
182+
* if (!strcmp(p, "anon_inode"))
183+
* Lf->ntype = Ntype = N_ANON_INODE;
184+
*
185+
* to detect our old anon_inode logic.
186+
*
187+
* Rather than mess with our internal sane inode data, just fix it
188+
* up here in getattr() by masking off the format bits.
189+
*/
172190
static int pidfs_getattr(struct mnt_idmap *idmap, const struct path *path,
173191
struct kstat *stat, u32 request_mask,
174192
unsigned int query_flags)
175193
{
176194
struct inode *inode = d_inode(path->dentry);
177195

178196
generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat);
197+
stat->mode &= ~S_IFMT;
179198
return 0;
180199
}
181200

@@ -199,12 +218,13 @@ static const struct super_operations pidfs_sops = {
199218
.statfs = simple_statfs,
200219
};
201220

221+
/*
222+
* 'lsof' has knowledge of out historical anon_inode use, and expects
223+
* the pidfs dentry name to start with 'anon_inode'.
224+
*/
202225
static char *pidfs_dname(struct dentry *dentry, char *buffer, int buflen)
203226
{
204-
struct inode *inode = d_inode(dentry);
205-
struct pid *pid = inode->i_private;
206-
207-
return dynamic_dname(buffer, buflen, "pidfd:[%llu]", pid->ino);
227+
return dynamic_dname(buffer, buflen, "anon_inode:[pidfd]");
208228
}
209229

210230
static const struct dentry_operations pidfs_dentry_operations = {

0 commit comments

Comments
 (0)