dynroot.c (6b93f350e55f3f2ee071dd41109d936abfba8ebf) | dynroot.c (499aa1ca4eb6602df38afaecb88fc14edf50cdbb) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* AFS dynamic root handling 3 * 4 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8#include <linux/fs.h> --- 100 unchanged lines hidden (view full) --- 109 * being created unnecessarily. 110 */ 111static int afs_probe_cell_name(struct dentry *dentry) 112{ 113 struct afs_cell *cell; 114 struct afs_net *net = afs_d2net(dentry); 115 const char *name = dentry->d_name.name; 116 size_t len = dentry->d_name.len; | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* AFS dynamic root handling 3 * 4 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. 5 * Written by David Howells (dhowells@redhat.com) 6 */ 7 8#include <linux/fs.h> --- 100 unchanged lines hidden (view full) --- 109 * being created unnecessarily. 110 */ 111static int afs_probe_cell_name(struct dentry *dentry) 112{ 113 struct afs_cell *cell; 114 struct afs_net *net = afs_d2net(dentry); 115 const char *name = dentry->d_name.name; 116 size_t len = dentry->d_name.len; |
117 char *result = NULL; |
|
117 int ret; 118 119 /* Names prefixed with a dot are R/W mounts. */ 120 if (name[0] == '.') { 121 if (len == 1) 122 return -EINVAL; 123 name++; 124 len--; 125 } 126 127 cell = afs_find_cell(net, name, len, afs_cell_trace_use_probe); 128 if (!IS_ERR(cell)) { 129 afs_unuse_cell(net, cell, afs_cell_trace_unuse_probe); 130 return 0; 131 } 132 133 ret = dns_query(net->net, "afsdb", name, len, "srv=1", | 118 int ret; 119 120 /* Names prefixed with a dot are R/W mounts. */ 121 if (name[0] == '.') { 122 if (len == 1) 123 return -EINVAL; 124 name++; 125 len--; 126 } 127 128 cell = afs_find_cell(net, name, len, afs_cell_trace_use_probe); 129 if (!IS_ERR(cell)) { 130 afs_unuse_cell(net, cell, afs_cell_trace_unuse_probe); 131 return 0; 132 } 133 134 ret = dns_query(net->net, "afsdb", name, len, "srv=1", |
134 NULL, NULL, false); 135 if (ret == -ENODATA || ret == -ENOKEY) | 135 &result, NULL, false); 136 if (ret == -ENODATA || ret == -ENOKEY || ret == 0) |
136 ret = -ENOENT; | 137 ret = -ENOENT; |
138 if (ret > 0 && ret >= sizeof(struct dns_server_list_v1_header)) { 139 struct dns_server_list_v1_header *v1 = (void *)result; 140 141 if (v1->hdr.zero == 0 && 142 v1->hdr.content == DNS_PAYLOAD_IS_SERVER_LIST && 143 v1->hdr.version == 1 && 144 (v1->status != DNS_LOOKUP_GOOD && 145 v1->status != DNS_LOOKUP_GOOD_WITH_BAD)) 146 return -ENOENT; 147 148 } 149 150 kfree(result); |
|
137 return ret; 138} 139 140/* 141 * Try to auto mount the mountpoint with pseudo directory, if the autocell 142 * operation is setted. 143 */ 144struct inode *afs_try_auto_mntpt(struct dentry *dentry, struct inode *dir) --- 102 unchanged lines hidden (view full) --- 247/* 248 * Dirs in the dynamic root don't need revalidation. 249 */ 250static int afs_dynroot_d_revalidate(struct dentry *dentry, unsigned int flags) 251{ 252 return 1; 253} 254 | 151 return ret; 152} 153 154/* 155 * Try to auto mount the mountpoint with pseudo directory, if the autocell 156 * operation is setted. 157 */ 158struct inode *afs_try_auto_mntpt(struct dentry *dentry, struct inode *dir) --- 102 unchanged lines hidden (view full) --- 261/* 262 * Dirs in the dynamic root don't need revalidation. 263 */ 264static int afs_dynroot_d_revalidate(struct dentry *dentry, unsigned int flags) 265{ 266 return 1; 267} 268 |
255/* 256 * Allow the VFS to enquire as to whether a dentry should be unhashed (mustn't 257 * sleep) 258 * - called from dput() when d_count is going to 0. 259 * - return 1 to request dentry be unhashed, 0 otherwise 260 */ 261static int afs_dynroot_d_delete(const struct dentry *dentry) 262{ 263 return d_really_is_positive(dentry); 264} 265 | |
266const struct dentry_operations afs_dynroot_dentry_operations = { 267 .d_revalidate = afs_dynroot_d_revalidate, | 269const struct dentry_operations afs_dynroot_dentry_operations = { 270 .d_revalidate = afs_dynroot_d_revalidate, |
268 .d_delete = afs_dynroot_d_delete, | 271 .d_delete = always_delete_dentry, |
269 .d_release = afs_d_release, 270 .d_automount = afs_d_automount, 271}; 272 273/* 274 * Create a manually added cell mount directory. 275 * - The caller must hold net->proc_cells_lock 276 */ --- 88 unchanged lines hidden (view full) --- 365 366/* 367 * When a dynamic root that's in the process of being destroyed, depopulate it 368 * of pinned directories. 369 */ 370void afs_dynroot_depopulate(struct super_block *sb) 371{ 372 struct afs_net *net = afs_sb2net(sb); | 272 .d_release = afs_d_release, 273 .d_automount = afs_d_automount, 274}; 275 276/* 277 * Create a manually added cell mount directory. 278 * - The caller must hold net->proc_cells_lock 279 */ --- 88 unchanged lines hidden (view full) --- 368 369/* 370 * When a dynamic root that's in the process of being destroyed, depopulate it 371 * of pinned directories. 372 */ 373void afs_dynroot_depopulate(struct super_block *sb) 374{ 375 struct afs_net *net = afs_sb2net(sb); |
373 struct dentry *root = sb->s_root, *subdir, *tmp; | 376 struct dentry *root = sb->s_root, *subdir; |
374 375 /* Prevent more subdirs from being created */ 376 mutex_lock(&net->proc_cells_lock); 377 if (net->dynroot_sb == sb) 378 net->dynroot_sb = NULL; 379 mutex_unlock(&net->proc_cells_lock); 380 381 if (root) { | 377 378 /* Prevent more subdirs from being created */ 379 mutex_lock(&net->proc_cells_lock); 380 if (net->dynroot_sb == sb) 381 net->dynroot_sb = NULL; 382 mutex_unlock(&net->proc_cells_lock); 383 384 if (root) { |
385 struct hlist_node *n; |
|
382 inode_lock(root->d_inode); 383 384 /* Remove all the pins for dirs created for manually added cells */ | 386 inode_lock(root->d_inode); 387 388 /* Remove all the pins for dirs created for manually added cells */ |
385 list_for_each_entry_safe(subdir, tmp, &root->d_subdirs, d_child) { | 389 hlist_for_each_entry_safe(subdir, n, &root->d_children, d_sib) { |
386 if (subdir->d_fsdata) { 387 subdir->d_fsdata = NULL; 388 dput(subdir); 389 } 390 } 391 392 inode_unlock(root->d_inode); 393 } 394} | 390 if (subdir->d_fsdata) { 391 subdir->d_fsdata = NULL; 392 dput(subdir); 393 } 394 } 395 396 inode_unlock(root->d_inode); 397 } 398} |