162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2019 Samsung Electronics Co., Ltd. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __VFS_CACHE_H__ 762306a36Sopenharmony_ci#define __VFS_CACHE_H__ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/file.h> 1062306a36Sopenharmony_ci#include <linux/fs.h> 1162306a36Sopenharmony_ci#include <linux/rwsem.h> 1262306a36Sopenharmony_ci#include <linux/spinlock.h> 1362306a36Sopenharmony_ci#include <linux/idr.h> 1462306a36Sopenharmony_ci#include <linux/workqueue.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "vfs.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* Windows style file permissions for extended response */ 1962306a36Sopenharmony_ci#define FILE_GENERIC_ALL 0x1F01FF 2062306a36Sopenharmony_ci#define FILE_GENERIC_READ 0x120089 2162306a36Sopenharmony_ci#define FILE_GENERIC_WRITE 0x120116 2262306a36Sopenharmony_ci#define FILE_GENERIC_EXECUTE 0X1200a0 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define KSMBD_START_FID 0 2562306a36Sopenharmony_ci#define KSMBD_NO_FID (INT_MAX) 2662306a36Sopenharmony_ci#define SMB2_NO_FID (0xFFFFFFFFFFFFFFFFULL) 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistruct ksmbd_conn; 2962306a36Sopenharmony_cistruct ksmbd_session; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistruct ksmbd_lock { 3262306a36Sopenharmony_ci struct file_lock *fl; 3362306a36Sopenharmony_ci struct list_head clist; 3462306a36Sopenharmony_ci struct list_head flist; 3562306a36Sopenharmony_ci struct list_head llist; 3662306a36Sopenharmony_ci unsigned int flags; 3762306a36Sopenharmony_ci int cmd; 3862306a36Sopenharmony_ci int zero_len; 3962306a36Sopenharmony_ci unsigned long long start; 4062306a36Sopenharmony_ci unsigned long long end; 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistruct stream { 4462306a36Sopenharmony_ci char *name; 4562306a36Sopenharmony_ci ssize_t size; 4662306a36Sopenharmony_ci}; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistruct ksmbd_inode { 4962306a36Sopenharmony_ci rwlock_t m_lock; 5062306a36Sopenharmony_ci atomic_t m_count; 5162306a36Sopenharmony_ci atomic_t op_count; 5262306a36Sopenharmony_ci /* opinfo count for streams */ 5362306a36Sopenharmony_ci atomic_t sop_count; 5462306a36Sopenharmony_ci struct dentry *m_de; 5562306a36Sopenharmony_ci unsigned int m_flags; 5662306a36Sopenharmony_ci struct hlist_node m_hash; 5762306a36Sopenharmony_ci struct list_head m_fp_list; 5862306a36Sopenharmony_ci struct list_head m_op_list; 5962306a36Sopenharmony_ci struct oplock_info *m_opinfo; 6062306a36Sopenharmony_ci __le32 m_fattr; 6162306a36Sopenharmony_ci}; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cienum { 6462306a36Sopenharmony_ci FP_NEW = 0, 6562306a36Sopenharmony_ci FP_INITED, 6662306a36Sopenharmony_ci FP_CLOSED 6762306a36Sopenharmony_ci}; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistruct ksmbd_file { 7062306a36Sopenharmony_ci struct file *filp; 7162306a36Sopenharmony_ci u64 persistent_id; 7262306a36Sopenharmony_ci u64 volatile_id; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci spinlock_t f_lock; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci struct ksmbd_inode *f_ci; 7762306a36Sopenharmony_ci struct ksmbd_inode *f_parent_ci; 7862306a36Sopenharmony_ci struct oplock_info __rcu *f_opinfo; 7962306a36Sopenharmony_ci struct ksmbd_conn *conn; 8062306a36Sopenharmony_ci struct ksmbd_tree_connect *tcon; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci atomic_t refcount; 8362306a36Sopenharmony_ci __le32 daccess; 8462306a36Sopenharmony_ci __le32 saccess; 8562306a36Sopenharmony_ci __le32 coption; 8662306a36Sopenharmony_ci __le32 cdoption; 8762306a36Sopenharmony_ci __u64 create_time; 8862306a36Sopenharmony_ci __u64 itime; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci bool is_nt_open; 9162306a36Sopenharmony_ci bool attrib_only; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci char client_guid[16]; 9462306a36Sopenharmony_ci char create_guid[16]; 9562306a36Sopenharmony_ci char app_instance_id[16]; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci struct stream stream; 9862306a36Sopenharmony_ci struct list_head node; 9962306a36Sopenharmony_ci struct list_head blocked_works; 10062306a36Sopenharmony_ci struct list_head lock_list; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci int durable_timeout; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci /* if ls is happening on directory, below is valid*/ 10562306a36Sopenharmony_ci struct ksmbd_readdir_data readdir_data; 10662306a36Sopenharmony_ci int dot_dotdot[2]; 10762306a36Sopenharmony_ci unsigned int f_state; 10862306a36Sopenharmony_ci bool reserve_lease_break; 10962306a36Sopenharmony_ci}; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic inline void set_ctx_actor(struct dir_context *ctx, 11262306a36Sopenharmony_ci filldir_t actor) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci ctx->actor = actor; 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci#define KSMBD_NR_OPEN_DEFAULT BITS_PER_LONG 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistruct ksmbd_file_table { 12062306a36Sopenharmony_ci rwlock_t lock; 12162306a36Sopenharmony_ci struct idr *idr; 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic inline bool has_file_id(u64 id) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci return id < KSMBD_NO_FID; 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic inline bool ksmbd_stream_fd(struct ksmbd_file *fp) 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci return fp->stream.name != NULL; 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ciint ksmbd_init_file_table(struct ksmbd_file_table *ft); 13562306a36Sopenharmony_civoid ksmbd_destroy_file_table(struct ksmbd_file_table *ft); 13662306a36Sopenharmony_ciint ksmbd_close_fd(struct ksmbd_work *work, u64 id); 13762306a36Sopenharmony_cistruct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, u64 id); 13862306a36Sopenharmony_cistruct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, u64 id); 13962306a36Sopenharmony_cistruct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id, 14062306a36Sopenharmony_ci u64 pid); 14162306a36Sopenharmony_civoid ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp); 14262306a36Sopenharmony_cistruct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d); 14362306a36Sopenharmony_civoid ksmbd_inode_put(struct ksmbd_inode *ci); 14462306a36Sopenharmony_cistruct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id); 14562306a36Sopenharmony_cistruct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid); 14662306a36Sopenharmony_cistruct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry); 14762306a36Sopenharmony_ciunsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp); 14862306a36Sopenharmony_cistruct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp); 14962306a36Sopenharmony_civoid ksmbd_close_tree_conn_fds(struct ksmbd_work *work); 15062306a36Sopenharmony_civoid ksmbd_close_session_fds(struct ksmbd_work *work); 15162306a36Sopenharmony_ciint ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode); 15262306a36Sopenharmony_ciint ksmbd_init_global_file_table(void); 15362306a36Sopenharmony_civoid ksmbd_free_global_file_table(void); 15462306a36Sopenharmony_civoid ksmbd_set_fd_limit(unsigned long limit); 15562306a36Sopenharmony_civoid ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp, 15662306a36Sopenharmony_ci unsigned int state); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci/* 15962306a36Sopenharmony_ci * INODE hash 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_ciint __init ksmbd_inode_hash_init(void); 16262306a36Sopenharmony_civoid ksmbd_release_inode_hash(void); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cienum KSMBD_INODE_STATUS { 16562306a36Sopenharmony_ci KSMBD_INODE_STATUS_OK, 16662306a36Sopenharmony_ci KSMBD_INODE_STATUS_UNKNOWN, 16762306a36Sopenharmony_ci KSMBD_INODE_STATUS_PENDING_DELETE, 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ciint ksmbd_query_inode_status(struct dentry *dentry); 17162306a36Sopenharmony_cibool ksmbd_inode_pending_delete(struct ksmbd_file *fp); 17262306a36Sopenharmony_civoid ksmbd_set_inode_pending_delete(struct ksmbd_file *fp); 17362306a36Sopenharmony_civoid ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp); 17462306a36Sopenharmony_civoid ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, 17562306a36Sopenharmony_ci int file_info); 17662306a36Sopenharmony_ciint ksmbd_init_file_cache(void); 17762306a36Sopenharmony_civoid ksmbd_exit_file_cache(void); 17862306a36Sopenharmony_ci#endif /* __VFS_CACHE_H__ */ 179