Skip to content

Commit 92f08e9

Browse files
dhowellsbrauner
authored andcommitted
afs: Make /afs/.<cell> as well as /afs/<cell> mountpoints
When a cell is instantiated, automatically create an /afs/.<cell> mountpoint to match the /afs/<cell> mountpoint to match other AFS clients. Signed-off-by: David Howells <[email protected]> Link: https://lore.kernel.org/r/[email protected] cc: Marc Dionne <[email protected]> cc: [email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 40384c8 commit 92f08e9

File tree

2 files changed

+41
-24
lines changed

2 files changed

+41
-24
lines changed

fs/afs/cell.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,20 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,
146146
return ERR_PTR(-ENOMEM);
147147
}
148148

149-
cell->name = kmalloc(namelen + 1, GFP_KERNEL);
149+
cell->name = kmalloc(1 + namelen + 1, GFP_KERNEL);
150150
if (!cell->name) {
151151
kfree(cell);
152152
return ERR_PTR(-ENOMEM);
153153
}
154154

155-
cell->net = net;
155+
cell->name[0] = '.';
156+
cell->name++;
156157
cell->name_len = namelen;
157158
for (i = 0; i < namelen; i++)
158159
cell->name[i] = tolower(name[i]);
159160
cell->name[i] = 0;
160161

162+
cell->net = net;
161163
refcount_set(&cell->ref, 1);
162164
atomic_set(&cell->active, 0);
163165
INIT_WORK(&cell->manager, afs_manage_cell_work);
@@ -211,7 +213,7 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,
211213
if (ret == -EINVAL)
212214
printk(KERN_ERR "kAFS: bad VL server IP address\n");
213215
error:
214-
kfree(cell->name);
216+
kfree(cell->name - 1);
215217
kfree(cell);
216218
_leave(" = %d", ret);
217219
return ERR_PTR(ret);
@@ -502,7 +504,7 @@ static void afs_cell_destroy(struct rcu_head *rcu)
502504
afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers));
503505
afs_unuse_cell(net, cell->alias_of, afs_cell_trace_unuse_alias);
504506
key_put(cell->anonymous_key);
505-
kfree(cell->name);
507+
kfree(cell->name - 1);
506508
kfree(cell);
507509

508510
afs_dec_cells_outstanding(net);
@@ -710,7 +712,8 @@ static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
710712
afs_proc_cell_remove(cell);
711713

712714
mutex_lock(&net->proc_cells_lock);
713-
hlist_del_rcu(&cell->proc_link);
715+
if (!hlist_unhashed(&cell->proc_link))
716+
hlist_del_rcu(&cell->proc_link);
714717
afs_dynroot_rmdir(net, cell);
715718
mutex_unlock(&net->proc_cells_lock);
716719

fs/afs/dynroot.c

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ const struct dentry_operations afs_dynroot_dentry_operations = {
271271
int afs_dynroot_mkdir(struct afs_net *net, struct afs_cell *cell)
272272
{
273273
struct super_block *sb = net->dynroot_sb;
274-
struct dentry *root, *subdir;
274+
struct dentry *root, *subdir, *dsubdir;
275+
char *dotname = cell->name - 1;
275276
int ret;
276277

277278
if (!sb || atomic_read(&sb->s_active) == 0)
@@ -286,34 +287,31 @@ int afs_dynroot_mkdir(struct afs_net *net, struct afs_cell *cell)
286287
goto unlock;
287288
}
288289

289-
/* Note that we're retaining an extra ref on the dentry */
290+
dsubdir = lookup_one_len(dotname, root, cell->name_len + 1);
291+
if (IS_ERR(dsubdir)) {
292+
ret = PTR_ERR(dsubdir);
293+
dput(subdir);
294+
goto unlock;
295+
}
296+
297+
/* Note that we're retaining extra refs on the dentries. */
290298
subdir->d_fsdata = (void *)1UL;
299+
dsubdir->d_fsdata = (void *)1UL;
291300
ret = 0;
292301
unlock:
293302
inode_unlock(root->d_inode);
294303
return ret;
295304
}
296305

297-
/*
298-
* Remove a manually added cell mount directory.
299-
* - The caller must hold net->proc_cells_lock
300-
*/
301-
void afs_dynroot_rmdir(struct afs_net *net, struct afs_cell *cell)
306+
static void afs_dynroot_rm_one_dir(struct dentry *root, const char *name, size_t name_len)
302307
{
303-
struct super_block *sb = net->dynroot_sb;
304-
struct dentry *root, *subdir;
305-
306-
if (!sb || atomic_read(&sb->s_active) == 0)
307-
return;
308-
309-
root = sb->s_root;
310-
inode_lock(root->d_inode);
308+
struct dentry *subdir;
311309

312310
/* Don't want to trigger a lookup call, which will re-add the cell */
313-
subdir = try_lookup_one_len(cell->name, root, cell->name_len);
311+
subdir = try_lookup_one_len(name, root, name_len);
314312
if (IS_ERR_OR_NULL(subdir)) {
315313
_debug("lookup %ld", PTR_ERR(subdir));
316-
goto no_dentry;
314+
return;
317315
}
318316

319317
_debug("rmdir %pd %u", subdir, d_count(subdir));
@@ -324,8 +322,24 @@ void afs_dynroot_rmdir(struct afs_net *net, struct afs_cell *cell)
324322
dput(subdir);
325323
}
326324
dput(subdir);
327-
no_dentry:
328-
inode_unlock(root->d_inode);
325+
}
326+
327+
/*
328+
* Remove a manually added cell mount directory.
329+
* - The caller must hold net->proc_cells_lock
330+
*/
331+
void afs_dynroot_rmdir(struct afs_net *net, struct afs_cell *cell)
332+
{
333+
struct super_block *sb = net->dynroot_sb;
334+
char *dotname = cell->name - 1;
335+
336+
if (!sb || atomic_read(&sb->s_active) == 0)
337+
return;
338+
339+
inode_lock(sb->s_root->d_inode);
340+
afs_dynroot_rm_one_dir(sb->s_root, cell->name, cell->name_len);
341+
afs_dynroot_rm_one_dir(sb->s_root, dotname, cell->name_len + 1);
342+
inode_unlock(sb->s_root->d_inode);
329343
_leave("");
330344
}
331345

0 commit comments

Comments
 (0)