/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2019 Samsung Electronics Co., Ltd. */ #ifndef __VFS_CACHE_H__ #define __VFS_CACHE_H__ #include #include #include #include #include #include #include "vfs.h" #include "mgmt/share_config.h" /* Windows style file permissions for extended response */ #define FILE_GENERIC_ALL 0x1F01FF #define FILE_GENERIC_READ 0x120089 #define FILE_GENERIC_WRITE 0x120116 #define FILE_GENERIC_EXECUTE 0X1200a0 #define KSMBD_START_FID 0 #define KSMBD_NO_FID (INT_MAX) #define SMB2_NO_FID (0xFFFFFFFFFFFFFFFFULL) struct ksmbd_conn; struct ksmbd_session; struct ksmbd_lock { struct file_lock *fl; struct list_head clist; struct list_head flist; struct list_head llist; unsigned int flags; int cmd; int zero_len; unsigned long long start; unsigned long long end; }; struct stream { char *name; ssize_t size; }; struct ksmbd_inode { struct rw_semaphore m_lock; atomic_t m_count; atomic_t op_count; /* opinfo count for streams */ atomic_t sop_count; struct dentry *m_de; unsigned int m_flags; struct hlist_node m_hash; struct list_head m_fp_list; struct list_head m_op_list; struct oplock_info *m_opinfo; __le32 m_fattr; }; enum { FP_NEW = 0, FP_INITED, FP_CLOSED }; struct ksmbd_file { struct file *filp; u64 persistent_id; u64 volatile_id; spinlock_t f_lock; struct ksmbd_inode *f_ci; struct ksmbd_inode *f_parent_ci; struct oplock_info __rcu *f_opinfo; struct ksmbd_conn *conn; struct ksmbd_tree_connect *tcon; atomic_t refcount; __le32 daccess; __le32 saccess; __le32 coption; __le32 cdoption; __u64 create_time; __u64 itime; bool is_nt_open; bool attrib_only; char client_guid[16]; char create_guid[16]; char app_instance_id[16]; struct stream stream; struct list_head node; struct list_head blocked_works; struct list_head lock_list; unsigned int durable_timeout; unsigned int durable_scavenger_timeout; /* if ls is happening on directory, below is valid*/ struct ksmbd_readdir_data readdir_data; int dot_dotdot[2]; unsigned int f_state; bool reserve_lease_break; bool is_durable; bool is_persistent; bool is_resilient; }; static inline void set_ctx_actor(struct dir_context *ctx, filldir_t actor) { ctx->actor = actor; } #define KSMBD_NR_OPEN_DEFAULT BITS_PER_LONG struct ksmbd_file_table { rwlock_t lock; struct idr *idr; }; static inline bool has_file_id(u64 id) { return id < KSMBD_NO_FID; } static inline bool ksmbd_stream_fd(struct ksmbd_file *fp) { return fp->stream.name != NULL; } int ksmbd_init_file_table(struct ksmbd_file_table *ft); void ksmbd_destroy_file_table(struct ksmbd_file_table *ft); int ksmbd_close_fd(struct ksmbd_work *work, u64 id); struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, u64 id); struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, u64 id); struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id, u64 pid); void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp); struct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d); void ksmbd_inode_put(struct ksmbd_inode *ci); struct ksmbd_file *ksmbd_lookup_global_fd(unsigned long long id); struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id); void ksmbd_put_durable_fd(struct ksmbd_file *fp); struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid); struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry); unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp); struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp); void ksmbd_launch_ksmbd_durable_scavenger(void); void ksmbd_stop_durable_scavenger(void); void ksmbd_close_tree_conn_fds(struct ksmbd_work *work); void ksmbd_close_session_fds(struct ksmbd_work *work); int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode); int ksmbd_init_global_file_table(void); void ksmbd_free_global_file_table(void); void ksmbd_set_fd_limit(unsigned long limit); void ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp, unsigned int state); /* * INODE hash */ int __init ksmbd_inode_hash_init(void); void ksmbd_release_inode_hash(void); enum KSMBD_INODE_STATUS { KSMBD_INODE_STATUS_OK, KSMBD_INODE_STATUS_UNKNOWN, KSMBD_INODE_STATUS_PENDING_DELETE, }; int ksmbd_query_inode_status(struct dentry *dentry); bool ksmbd_inode_pending_delete(struct ksmbd_file *fp); void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp); void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp); void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, int file_info); int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp); int ksmbd_validate_name_reconnect(struct ksmbd_share_config *share, struct ksmbd_file *fp, char *name); int ksmbd_init_file_cache(void); void ksmbd_exit_file_cache(void); #endif /* __VFS_CACHE_H__ */