On Fri, May 31, 2024 at 05:30:45PM +0100, Al Viro wrote: > static inline struct fd_err file_fd_err(struct file *f, bool is_cloned) > { > if (IS_ERR(f)) > return (struct fd_err){PTR_ERR(f)}; > else > return (struct fd_err){(unsigned long)f | is_cloned}; > } > > (or, perhaps, file_fd_cloned and file_fd_borrowed, to get rid of > 'is_cloned' argument in public API; need to play around a bit and > see what works better - the interesting part is what the constructor > for struct fd would look like) ... along with static inline struct fd_err ERR_FD(long n) { return (struct fd_err){.word = (unsigned long)n}; } yielding > static struct fd_err ovl_real_fdget_meta(const struct file *file, bool allow_meta) > { > struct dentry *dentry = file_dentry(file); > struct path realpath; > int err; > > if (allow_meta) { > ovl_path_real(dentry, &realpath); > } else { > /* lazy lookup and verify of lowerdata */ > err = ovl_verify_lowerdata(dentry); > if (err) return ERR_FD(err); > > ovl_path_realdata(dentry, &realpath); > } > if (!realpath.dentry) return ERR_FD(-EIO); > > /* Has it been copied up since we'd opened it? */ > if (unlikely(file_inode(real->file) != d_inode(realpath.dentry))) return file_fd_cloned(ovl_open_realfile(file, &realpath)); > > /* Did the flags change since open? */ > if (unlikely((file->f_flags ^ real->file->f_flags) & ~OVL_OPEN_FLAGS)) { > err = ovl_change_flags(real->file, file->f_flags); > if (err) return ERR_FD(err); > } > return file_fd_borrowed(file->private_data); > }