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