162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * V9FS FID Management
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#ifndef FS_9P_FID_H
862306a36Sopenharmony_ci#define FS_9P_FID_H
962306a36Sopenharmony_ci#include <linux/list.h>
1062306a36Sopenharmony_ci#include "v9fs.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistruct p9_fid *v9fs_fid_find_inode(struct inode *inode, bool want_writeable,
1362306a36Sopenharmony_ci	kuid_t uid, bool any);
1462306a36Sopenharmony_cistruct p9_fid *v9fs_fid_lookup(struct dentry *dentry);
1562306a36Sopenharmony_cistatic inline struct p9_fid *v9fs_parent_fid(struct dentry *dentry)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	return v9fs_fid_lookup(dentry->d_parent);
1862306a36Sopenharmony_ci}
1962306a36Sopenharmony_civoid v9fs_fid_add(struct dentry *dentry, struct p9_fid **fid);
2062306a36Sopenharmony_civoid v9fs_open_fid_add(struct inode *inode, struct p9_fid **fid);
2162306a36Sopenharmony_cistatic inline struct p9_fid *clone_fid(struct p9_fid *fid)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	return IS_ERR(fid) ? fid :  p9_client_walk(fid, 0, NULL, 1);
2462306a36Sopenharmony_ci}
2562306a36Sopenharmony_cistatic inline struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
2662306a36Sopenharmony_ci{
2762306a36Sopenharmony_ci	struct p9_fid *fid, *nfid;
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	fid = v9fs_fid_lookup(dentry);
3062306a36Sopenharmony_ci	if (!fid || IS_ERR(fid))
3162306a36Sopenharmony_ci		return fid;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	nfid = clone_fid(fid);
3462306a36Sopenharmony_ci	p9_fid_put(fid);
3562306a36Sopenharmony_ci	return nfid;
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci/**
3862306a36Sopenharmony_ci * v9fs_fid_addmodes - add cache flags to fid mode (for client use only)
3962306a36Sopenharmony_ci * @fid: fid to augment
4062306a36Sopenharmony_ci * @s_flags: session info mount flags
4162306a36Sopenharmony_ci * @s_cache: session info cache flags
4262306a36Sopenharmony_ci * @f_flags: unix open flags
4362306a36Sopenharmony_ci *
4462306a36Sopenharmony_ci * make sure mode reflects flags of underlying mounts
4562306a36Sopenharmony_ci * also qid.version == 0 reflects a synthetic or legacy file system
4662306a36Sopenharmony_ci * NOTE: these are set after open so only reflect 9p client not
4762306a36Sopenharmony_ci * underlying file system on server.
4862306a36Sopenharmony_ci */
4962306a36Sopenharmony_cistatic inline void v9fs_fid_add_modes(struct p9_fid *fid, unsigned int s_flags,
5062306a36Sopenharmony_ci	unsigned int s_cache, unsigned int f_flags)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	if (fid->qid.type != P9_QTFILE)
5362306a36Sopenharmony_ci		return;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	if ((!s_cache) ||
5662306a36Sopenharmony_ci	   ((fid->qid.version == 0) && !(s_flags & V9FS_IGNORE_QV)) ||
5762306a36Sopenharmony_ci	   (s_flags & V9FS_DIRECT_IO) || (f_flags & O_DIRECT)) {
5862306a36Sopenharmony_ci		fid->mode |= P9L_DIRECT; /* no read or write cache */
5962306a36Sopenharmony_ci	} else if ((!(s_cache & CACHE_WRITEBACK)) ||
6062306a36Sopenharmony_ci				(f_flags & O_DSYNC) || (s_flags & V9FS_SYNC)) {
6162306a36Sopenharmony_ci		fid->mode |= P9L_NOWRITECACHE;
6262306a36Sopenharmony_ci	}
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci#endif
65