1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Copyright (C) 2019 Samsung Electronics Co., Ltd. 4 */ 5 6 #ifndef __VFS_CACHE_H__ 7 #define __VFS_CACHE_H__ 8 9 #include <linux/file.h> 10 #include <linux/fs.h> 11 #include <linux/mutex.h> 12 #include <linux/rwsem.h> 13 #include <linux/spinlock.h> 14 #include <linux/idr.h> 15 #include <linux/workqueue.h> 16 17 #include "vfs.h" 18 #include "mgmt/share_config.h" 19 20 /* Windows style file permissions for extended response */ 21 #define FILE_GENERIC_ALL 0x1F01FF 22 #define FILE_GENERIC_READ 0x120089 23 #define FILE_GENERIC_WRITE 0x120116 24 #define FILE_GENERIC_EXECUTE 0X1200a0 25 26 #define KSMBD_START_FID 0 27 #define KSMBD_NO_FID (INT_MAX) 28 #define SMB2_NO_FID (0xFFFFFFFFFFFFFFFFULL) 29 30 struct ksmbd_conn; 31 struct ksmbd_session; 32 33 struct ksmbd_lock { 34 struct file_lock *fl; 35 struct list_head clist; 36 struct list_head flist; 37 struct list_head llist; 38 unsigned int flags; 39 int cmd; 40 int zero_len; 41 unsigned long long start; 42 unsigned long long end; 43 }; 44 45 struct stream { 46 char *name; 47 ssize_t size; 48 loff_t pos; 49 }; 50 51 struct ksmbd_inode { 52 struct rw_semaphore m_lock; 53 atomic_t m_count; 54 atomic_t op_count; 55 /* opinfo count for streams */ 56 atomic_t sop_count; 57 struct dentry *m_de; 58 unsigned int m_flags; 59 struct hlist_node m_hash; 60 struct list_head m_fp_list; 61 struct list_head m_op_list; 62 struct oplock_info *m_opinfo; 63 __le32 m_fattr; 64 }; 65 66 enum { 67 FP_NEW = 0, 68 FP_INITED, 69 FP_CLOSED 70 }; 71 72 /* Owner information for durable handle reconnect */ 73 struct durable_owner { 74 unsigned int uid; 75 unsigned int gid; 76 char *name; 77 }; 78 79 struct ksmbd_file { 80 struct file *filp; 81 u64 persistent_id; 82 u64 volatile_id; 83 84 spinlock_t f_lock; 85 86 struct ksmbd_inode *f_ci; 87 struct ksmbd_inode *f_parent_ci; 88 struct oplock_info __rcu *f_opinfo; 89 struct ksmbd_conn *conn; 90 struct ksmbd_tree_connect *tcon; 91 92 atomic_t refcount; 93 __le32 daccess; 94 __le32 saccess; 95 __le32 coption; 96 __le32 cdoption; 97 __u64 create_time; 98 __u64 itime; 99 100 bool is_nt_open; 101 bool attrib_only; 102 103 char client_guid[16]; 104 char create_guid[16]; 105 char app_instance_id[16]; 106 107 struct stream stream; 108 struct list_head node; 109 struct list_head blocked_works; 110 struct list_head lock_list; 111 112 unsigned int durable_timeout; 113 unsigned int durable_scavenger_timeout; 114 115 /* if ls is happening on directory, below is valid*/ 116 struct ksmbd_readdir_data readdir_data; 117 struct mutex readdir_lock; 118 int dot_dotdot[2]; 119 unsigned int f_state; 120 bool reserve_lease_break; 121 bool is_durable; 122 bool is_persistent; 123 bool is_resilient; 124 125 bool is_posix_ctxt; 126 struct durable_owner owner; 127 }; 128 129 static inline void set_ctx_actor(struct dir_context *ctx, 130 filldir_t actor) 131 { 132 ctx->actor = actor; 133 } 134 135 #define KSMBD_NR_OPEN_DEFAULT BITS_PER_LONG 136 137 struct ksmbd_file_table { 138 rwlock_t lock; 139 struct idr *idr; 140 }; 141 142 static inline bool has_file_id(u64 id) 143 { 144 return id < KSMBD_NO_FID; 145 } 146 147 static inline bool ksmbd_stream_fd(struct ksmbd_file *fp) 148 { 149 return fp->stream.name != NULL; 150 } 151 152 int ksmbd_init_file_table(struct ksmbd_file_table *ft); 153 void ksmbd_destroy_file_table(struct ksmbd_session *sess); 154 int ksmbd_close_fd(struct ksmbd_work *work, u64 id); 155 struct ksmbd_file *ksmbd_lookup_fd_fast(struct ksmbd_work *work, u64 id); 156 struct ksmbd_file *ksmbd_lookup_foreign_fd(struct ksmbd_work *work, u64 id); 157 struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id, 158 u64 pid); 159 void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp); 160 struct ksmbd_inode *ksmbd_inode_lookup_lock(struct dentry *d); 161 void ksmbd_inode_put(struct ksmbd_inode *ci); 162 struct ksmbd_file *ksmbd_lookup_global_fd(unsigned long long id); 163 struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id); 164 void ksmbd_put_durable_fd(struct ksmbd_file *fp); 165 struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid); 166 struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry); 167 unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp); 168 struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp); 169 void ksmbd_launch_ksmbd_durable_scavenger(void); 170 void ksmbd_stop_durable_scavenger(void); 171 void ksmbd_close_tree_conn_fds(struct ksmbd_work *work); 172 void ksmbd_close_session_fds(struct ksmbd_work *work); 173 int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode); 174 int ksmbd_init_global_file_table(void); 175 void ksmbd_free_global_file_table(void); 176 void ksmbd_set_fd_limit(unsigned long limit); 177 int ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp, 178 unsigned int state); 179 bool ksmbd_vfs_compare_durable_owner(struct ksmbd_file *fp, 180 struct ksmbd_user *user); 181 182 /* 183 * INODE hash 184 */ 185 int __init ksmbd_inode_hash_init(void); 186 void ksmbd_release_inode_hash(void); 187 188 enum KSMBD_INODE_STATUS { 189 KSMBD_INODE_STATUS_OK, 190 KSMBD_INODE_STATUS_UNKNOWN, 191 KSMBD_INODE_STATUS_PENDING_DELETE, 192 }; 193 194 int ksmbd_query_inode_status(struct dentry *dentry); 195 bool ksmbd_inode_pending_delete(struct ksmbd_file *fp); 196 void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp); 197 void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp); 198 void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, 199 int file_info); 200 int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp); 201 int ksmbd_validate_name_reconnect(struct ksmbd_share_config *share, 202 struct ksmbd_file *fp, char *name); 203 int ksmbd_init_file_cache(void); 204 void ksmbd_exit_file_cache(void); 205 #endif /* __VFS_CACHE_H__ */ 206