162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  Functions to handle the cached directory entries
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (c) 2022, Ronnie Sahlberg <lsahlber@redhat.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef _CACHED_DIR_H
962306a36Sopenharmony_ci#define _CACHED_DIR_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistruct cached_dirent {
1362306a36Sopenharmony_ci	struct list_head entry;
1462306a36Sopenharmony_ci	char *name;
1562306a36Sopenharmony_ci	int namelen;
1662306a36Sopenharmony_ci	loff_t pos;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci	struct cifs_fattr fattr;
1962306a36Sopenharmony_ci};
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistruct cached_dirents {
2262306a36Sopenharmony_ci	bool is_valid:1;
2362306a36Sopenharmony_ci	bool is_failed:1;
2462306a36Sopenharmony_ci	struct dir_context *ctx; /*
2562306a36Sopenharmony_ci				  * Only used to make sure we only take entries
2662306a36Sopenharmony_ci				  * from a single context. Never dereferenced.
2762306a36Sopenharmony_ci				  */
2862306a36Sopenharmony_ci	struct mutex de_mutex;
2962306a36Sopenharmony_ci	int pos;		 /* Expected ctx->pos */
3062306a36Sopenharmony_ci	struct list_head entries;
3162306a36Sopenharmony_ci};
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistruct cached_fid {
3462306a36Sopenharmony_ci	struct list_head entry;
3562306a36Sopenharmony_ci	struct cached_fids *cfids;
3662306a36Sopenharmony_ci	const char *path;
3762306a36Sopenharmony_ci	bool has_lease:1;
3862306a36Sopenharmony_ci	bool is_open:1;
3962306a36Sopenharmony_ci	bool on_list:1;
4062306a36Sopenharmony_ci	bool file_all_info_is_valid:1;
4162306a36Sopenharmony_ci	unsigned long time; /* jiffies of when lease was taken */
4262306a36Sopenharmony_ci	struct kref refcount;
4362306a36Sopenharmony_ci	struct cifs_fid fid;
4462306a36Sopenharmony_ci	spinlock_t fid_lock;
4562306a36Sopenharmony_ci	struct cifs_tcon *tcon;
4662306a36Sopenharmony_ci	struct dentry *dentry;
4762306a36Sopenharmony_ci	struct work_struct lease_break;
4862306a36Sopenharmony_ci	struct smb2_file_all_info file_all_info;
4962306a36Sopenharmony_ci	struct cached_dirents dirents;
5062306a36Sopenharmony_ci};
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/* default MAX_CACHED_FIDS is 16 */
5362306a36Sopenharmony_cistruct cached_fids {
5462306a36Sopenharmony_ci	/* Must be held when:
5562306a36Sopenharmony_ci	 * - accessing the cfids->entries list
5662306a36Sopenharmony_ci	 */
5762306a36Sopenharmony_ci	spinlock_t cfid_list_lock;
5862306a36Sopenharmony_ci	int num_entries;
5962306a36Sopenharmony_ci	struct list_head entries;
6062306a36Sopenharmony_ci	struct delayed_work laundromat_work;
6162306a36Sopenharmony_ci};
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciextern struct cached_fids *init_cached_dirs(void);
6462306a36Sopenharmony_ciextern void free_cached_dirs(struct cached_fids *cfids);
6562306a36Sopenharmony_ciextern int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
6662306a36Sopenharmony_ci			   const char *path,
6762306a36Sopenharmony_ci			   struct cifs_sb_info *cifs_sb,
6862306a36Sopenharmony_ci			   bool lookup_only, struct cached_fid **cfid);
6962306a36Sopenharmony_ciextern int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
7062306a36Sopenharmony_ci				     struct dentry *dentry,
7162306a36Sopenharmony_ci				     struct cached_fid **cfid);
7262306a36Sopenharmony_ciextern void close_cached_dir(struct cached_fid *cfid);
7362306a36Sopenharmony_ciextern void drop_cached_dir_by_name(const unsigned int xid,
7462306a36Sopenharmony_ci				    struct cifs_tcon *tcon,
7562306a36Sopenharmony_ci				    const char *name,
7662306a36Sopenharmony_ci				    struct cifs_sb_info *cifs_sb);
7762306a36Sopenharmony_ciextern void close_all_cached_dirs(struct cifs_sb_info *cifs_sb);
7862306a36Sopenharmony_ciextern void invalidate_all_cached_dirs(struct cifs_tcon *tcon);
7962306a36Sopenharmony_ciextern int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16]);
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#endif			/* _CACHED_DIR_H */
82