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}