1 /* 2 * Copyright (c) 2002, 2007 Red Hat, Inc. All rights reserved. 3 * 4 * This software may be freely redistributed under the terms of the 5 * GNU General Public License. 6 * 7 * You should have received a copy of the GNU General Public License 8 * along with this program; if not, write to the Free Software 9 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 10 * 11 * Authors: David Woodhouse <dwmw2@infradead.org> 12 * David Howells <dhowells@redhat.com> 13 * 14 */ 15 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/init.h> 19 #include <linux/circ_buf.h> 20 #include <linux/sched.h> 21 #include "internal.h" 22 23 /* 24 * Handle invalidation of an mmap'd file. We invalidate all the PTEs referring 25 * to the pages in this file's pagecache, forcing the kernel to go through 26 * ->fault() or ->page_mkwrite() - at which point we can handle invalidation 27 * more fully. 28 */ 29 void afs_invalidate_mmap_work(struct work_struct *work) 30 { 31 struct afs_vnode *vnode = container_of(work, struct afs_vnode, cb_work); 32 33 unmap_mapping_pages(vnode->netfs.inode.i_mapping, 0, 0, false); 34 } 35 36 static void afs_volume_init_callback(struct afs_volume *volume) 37 { 38 struct afs_vnode *vnode; 39 40 down_read(&volume->open_mmaps_lock); 41 42 list_for_each_entry(vnode, &volume->open_mmaps, cb_mmap_link) { 43 if (vnode->cb_v_check != atomic_read(&volume->cb_v_break)) { 44 afs_clear_cb_promise(vnode, afs_cb_promise_clear_vol_init_cb); 45 queue_work(system_dfl_wq, &vnode->cb_work); 46 } 47 } 48 49 up_read(&volume->open_mmaps_lock); 50 } 51 52 /* 53 * Allow the fileserver to request callback state (re-)initialisation. 54 * Unfortunately, UUIDs are not guaranteed unique. 55 */ 56 void afs_init_callback_state(struct afs_server *server) 57 { 58 struct afs_server_entry *se; 59 60 down_read(&server->cell->vs_lock); 61 62 list_for_each_entry(se, &server->volumes, slink) { 63 se->cb_expires_at = AFS_NO_CB_PROMISE; 64 se->volume->cb_expires_at = AFS_NO_CB_PROMISE; 65 trace_afs_cb_v_break(se->volume->vid, atomic_read(&se->volume->cb_v_break), 66 afs_cb_break_for_s_reinit); 67 if (!list_empty(&se->volume->open_mmaps)) 68 afs_volume_init_callback(se->volume); 69 } 70 71 up_read(&server->cell->vs_lock); 72 } 73 74 /* 75 * actually break a callback 76 */ 77 void __afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason) 78 { 79 _enter(""); 80 81 clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags); 82 if (afs_clear_cb_promise(vnode, afs_cb_promise_clear_cb_break)) { 83 vnode->cb_break++; 84 vnode->cb_v_check = atomic_read(&vnode->volume->cb_v_break); 85 afs_clear_permits(vnode); 86 87 if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB) 88 afs_lock_may_be_available(vnode); 89 90 if (reason != afs_cb_break_for_deleted && 91 vnode->status.type == AFS_FTYPE_FILE && 92 atomic_read(&vnode->cb_nr_mmap)) 93 queue_work(system_dfl_wq, &vnode->cb_work); 94 95 trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, true); 96 } else { 97 trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, false); 98 } 99 } 100 101 void afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason) 102 { 103 write_seqlock(&vnode->cb_lock); 104 __afs_break_callback(vnode, reason); 105 write_sequnlock(&vnode->cb_lock); 106 } 107 108 /* 109 * Look up a volume by volume ID under RCU conditions. 110 */ 111 static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell, 112 afs_volid_t vid) 113 { 114 struct afs_volume *volume = NULL; 115 struct rb_node *p; 116 117 scoped_seqlock_read(&cell->volume_lock, ss_lock) { 118 /* Unfortunately, rbtree walking doesn't give reliable results 119 * under just the RCU read lock, so we have to check for 120 * changes. 121 */ 122 p = rcu_dereference_raw(cell->volumes.rb_node); 123 while (p) { 124 volume = rb_entry(p, struct afs_volume, cell_node); 125 126 if (volume->vid < vid) 127 p = rcu_dereference_raw(p->rb_left); 128 else if (volume->vid > vid) 129 p = rcu_dereference_raw(p->rb_right); 130 else 131 break; 132 volume = NULL; 133 } 134 135 if (volume && afs_try_get_volume(volume, afs_volume_trace_get_callback)) 136 break; 137 volume = NULL; 138 } 139 140 return volume; 141 } 142 143 /* 144 * Allow the fileserver to break callbacks at the volume-level. This is 145 * typically done when, for example, a R/W volume is snapshotted to a R/O 146 * volume (the only way to change an R/O volume). It may also, however, happen 147 * when a volserver takes control of a volume (offlining it, moving it, etc.). 148 * 149 * Every file in that volume will need to be reevaluated. 150 */ 151 static void afs_break_volume_callback(struct afs_server *server, 152 struct afs_volume *volume) 153 __releases(RCU) 154 { 155 struct afs_server_list *slist = rcu_dereference(volume->servers); 156 unsigned int i, cb_v_break; 157 158 write_lock(&volume->cb_v_break_lock); 159 160 for (i = 0; i < slist->nr_servers; i++) 161 if (slist->servers[i].server == server) 162 slist->servers[i].cb_expires_at = AFS_NO_CB_PROMISE; 163 volume->cb_expires_at = AFS_NO_CB_PROMISE; 164 165 cb_v_break = atomic_inc_return_release(&volume->cb_v_break); 166 trace_afs_cb_v_break(volume->vid, cb_v_break, afs_cb_break_for_volume_callback); 167 168 write_unlock(&volume->cb_v_break_lock); 169 rcu_read_unlock(); 170 171 if (!list_empty(&volume->open_mmaps)) 172 afs_volume_init_callback(volume); 173 } 174 175 /* 176 * allow the fileserver to explicitly break one callback 177 * - happens when 178 * - the backing file is changed 179 * - a lock is released 180 */ 181 static void afs_break_one_callback(struct afs_server *server, 182 struct afs_volume *volume, 183 struct afs_fid *fid) 184 { 185 struct super_block *sb; 186 struct afs_vnode *vnode; 187 struct inode *inode; 188 189 /* See if we can find a matching inode - even an I_NEW inode needs to 190 * be marked as it can have its callback broken before we finish 191 * setting up the local inode. 192 */ 193 sb = rcu_dereference(volume->sb); 194 if (!sb) 195 return; 196 197 inode = find_inode_rcu(sb, fid->vnode, afs_ilookup5_test_by_fid, fid); 198 if (inode) { 199 vnode = AFS_FS_I(inode); 200 afs_break_callback(vnode, afs_cb_break_for_callback); 201 } else { 202 trace_afs_cb_miss(fid, afs_cb_break_for_callback); 203 } 204 } 205 206 static void afs_break_some_callbacks(struct afs_server *server, 207 struct afs_callback_break *cbb, 208 size_t *_count) 209 { 210 struct afs_callback_break *residue = cbb; 211 struct afs_volume *volume; 212 afs_volid_t vid = cbb->fid.vid; 213 size_t i; 214 215 rcu_read_lock(); 216 volume = afs_lookup_volume_rcu(server->cell, vid); 217 if (!volume) { 218 /* Ignore breaks on unknown volumes. */ 219 rcu_read_unlock(); 220 *_count = 0; 221 } else if (cbb->fid.vnode == 0 && cbb->fid.unique == 0) { 222 afs_break_volume_callback(server, volume); 223 *_count -= 1; 224 if (*_count) 225 memmove(cbb, cbb + 1, sizeof(*cbb) * *_count); 226 } else { 227 /* TODO: Find all matching volumes if we couldn't match the server and 228 * break them anyway. 229 */ 230 231 for (i = *_count; i > 0; cbb++, i--) { 232 if (cbb->fid.vid == vid) { 233 _debug("- Fid { vl=%08llx n=%llu u=%u }", 234 cbb->fid.vid, 235 cbb->fid.vnode, 236 cbb->fid.unique); 237 --*_count; 238 if (volume) 239 afs_break_one_callback(server, volume, &cbb->fid); 240 } else { 241 *residue++ = *cbb; 242 } 243 } 244 rcu_read_unlock(); 245 } 246 247 afs_put_volume(volume, afs_volume_trace_put_callback); 248 } 249 250 /* 251 * allow the fileserver to break callback promises 252 */ 253 void afs_break_callbacks(struct afs_server *server, size_t count, 254 struct afs_callback_break *callbacks) 255 { 256 _enter("%p,%zu,", server, count); 257 258 ASSERT(server != NULL); 259 260 while (count > 0) 261 afs_break_some_callbacks(server, callbacks, &count); 262 } 263