1 | /* SPDX-License-Identifier: LGPL-2.1 */ |
2 | /* |
3 | * CIFS filesystem cache interface definitions |
4 | * |
5 | * Copyright (c) 2010 Novell, Inc. |
6 | * Authors(s): Suresh Jayaraman (sjayaraman@suse.de> |
7 | * |
8 | */ |
9 | #ifndef _CIFS_FSCACHE_H |
10 | #define _CIFS_FSCACHE_H |
11 | |
12 | #include <linux/swap.h> |
13 | #include <linux/fscache.h> |
14 | |
15 | #include "cifsglob.h" |
16 | |
17 | /* |
18 | * Coherency data attached to CIFS volume within the cache |
19 | */ |
20 | struct cifs_fscache_volume_coherency_data { |
21 | __le64 resource_id; /* unique server resource id */ |
22 | __le64 vol_create_time; |
23 | __le32 vol_serial_number; |
24 | } __packed; |
25 | |
26 | /* |
27 | * Coherency data attached to CIFS inode within the cache. |
28 | */ |
29 | struct cifs_fscache_inode_coherency_data { |
30 | __le64 last_write_time_sec; |
31 | __le64 last_change_time_sec; |
32 | __le32 last_write_time_nsec; |
33 | __le32 last_change_time_nsec; |
34 | }; |
35 | |
36 | #ifdef CONFIG_CIFS_FSCACHE |
37 | |
38 | /* |
39 | * fscache.c |
40 | */ |
41 | extern int cifs_fscache_get_super_cookie(struct cifs_tcon *); |
42 | extern void cifs_fscache_release_super_cookie(struct cifs_tcon *); |
43 | |
44 | extern void cifs_fscache_get_inode_cookie(struct inode *inode); |
45 | extern void cifs_fscache_release_inode_cookie(struct inode *); |
46 | extern void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update); |
47 | |
48 | static inline |
49 | void cifs_fscache_fill_coherency(struct inode *inode, |
50 | struct cifs_fscache_inode_coherency_data *cd) |
51 | { |
52 | struct timespec64 ctime = inode_get_ctime(inode); |
53 | struct timespec64 mtime = inode_get_mtime(inode); |
54 | |
55 | memset(cd, 0, sizeof(*cd)); |
56 | cd->last_write_time_sec = cpu_to_le64(mtime.tv_sec); |
57 | cd->last_write_time_nsec = cpu_to_le32(mtime.tv_nsec); |
58 | cd->last_change_time_sec = cpu_to_le64(ctime.tv_sec); |
59 | cd->last_change_time_nsec = cpu_to_le32(ctime.tv_nsec); |
60 | } |
61 | |
62 | |
63 | static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) |
64 | { |
65 | return netfs_i_cookie(ctx: &CIFS_I(inode)->netfs); |
66 | } |
67 | |
68 | static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags) |
69 | { |
70 | struct cifs_fscache_inode_coherency_data cd; |
71 | |
72 | cifs_fscache_fill_coherency(inode, cd: &cd); |
73 | fscache_invalidate(cookie: cifs_inode_cookie(inode), aux_data: &cd, |
74 | size: i_size_read(inode), flags); |
75 | } |
76 | |
77 | extern int __cifs_fscache_query_occupancy(struct inode *inode, |
78 | pgoff_t first, unsigned int nr_pages, |
79 | pgoff_t *_data_first, |
80 | unsigned int *_data_nr_pages); |
81 | |
82 | static inline int cifs_fscache_query_occupancy(struct inode *inode, |
83 | pgoff_t first, unsigned int nr_pages, |
84 | pgoff_t *_data_first, |
85 | unsigned int *_data_nr_pages) |
86 | { |
87 | if (!cifs_inode_cookie(inode)) |
88 | return -ENOBUFS; |
89 | return __cifs_fscache_query_occupancy(inode, first, nr_pages, |
90 | _data_first, _data_nr_pages); |
91 | } |
92 | |
93 | extern int __cifs_readpage_from_fscache(struct inode *pinode, struct page *ppage); |
94 | extern void __cifs_readahead_to_fscache(struct inode *pinode, loff_t pos, size_t len); |
95 | |
96 | |
97 | static inline int cifs_readpage_from_fscache(struct inode *inode, |
98 | struct page *page) |
99 | { |
100 | if (cifs_inode_cookie(inode)) |
101 | return __cifs_readpage_from_fscache(pinode: inode, ppage: page); |
102 | return -ENOBUFS; |
103 | } |
104 | |
105 | static inline void cifs_readahead_to_fscache(struct inode *inode, |
106 | loff_t pos, size_t len) |
107 | { |
108 | if (cifs_inode_cookie(inode)) |
109 | __cifs_readahead_to_fscache(pinode: inode, pos, len); |
110 | } |
111 | |
112 | static inline bool cifs_fscache_enabled(struct inode *inode) |
113 | { |
114 | return fscache_cookie_enabled(cifs_inode_cookie(inode)); |
115 | } |
116 | |
117 | #else /* CONFIG_CIFS_FSCACHE */ |
118 | static inline |
119 | void cifs_fscache_fill_coherency(struct inode *inode, |
120 | struct cifs_fscache_inode_coherency_data *cd) |
121 | { |
122 | } |
123 | |
124 | static inline int cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) { return 0; } |
125 | static inline void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) {} |
126 | |
127 | static inline void cifs_fscache_get_inode_cookie(struct inode *inode) {} |
128 | static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {} |
129 | static inline void cifs_fscache_unuse_inode_cookie(struct inode *inode, bool update) {} |
130 | static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) { return NULL; } |
131 | static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags) {} |
132 | static inline bool cifs_fscache_enabled(struct inode *inode) { return false; } |
133 | |
134 | static inline int cifs_fscache_query_occupancy(struct inode *inode, |
135 | pgoff_t first, unsigned int nr_pages, |
136 | pgoff_t *_data_first, |
137 | unsigned int *_data_nr_pages) |
138 | { |
139 | *_data_first = ULONG_MAX; |
140 | *_data_nr_pages = 0; |
141 | return -ENOBUFS; |
142 | } |
143 | |
144 | static inline int |
145 | cifs_readpage_from_fscache(struct inode *inode, struct page *page) |
146 | { |
147 | return -ENOBUFS; |
148 | } |
149 | |
150 | static inline |
151 | void cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len) {} |
152 | |
153 | #endif /* CONFIG_CIFS_FSCACHE */ |
154 | |
155 | #endif /* _CIFS_FSCACHE_H */ |
156 | |