Skip to content

Commit 836bb70

Browse files
dhowellsbrauner
authored andcommitted
afs: Make afs_mkdir() locally initialise a new directory's content
Initialise a new directory's content when it is created by mkdir locally rather than downloading the content from the server as we can predict what it's going to look like. 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 e2d46f2 commit 836bb70

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

fs/afs/dir.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,6 +1264,7 @@ void afs_check_for_remote_deletion(struct afs_operation *op)
12641264
*/
12651265
static void afs_vnode_new_inode(struct afs_operation *op)
12661266
{
1267+
struct afs_vnode_param *dvp = &op->file[0];
12671268
struct afs_vnode_param *vp = &op->file[1];
12681269
struct afs_vnode *vnode;
12691270
struct inode *inode;
@@ -1283,6 +1284,8 @@ static void afs_vnode_new_inode(struct afs_operation *op)
12831284

12841285
vnode = AFS_FS_I(inode);
12851286
set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
1287+
if (S_ISDIR(inode->i_mode))
1288+
afs_mkdir_init_dir(vnode, dvp->vnode);
12861289
if (!afs_op_error(op))
12871290
afs_cache_permit(vnode, op->key, vnode->cb_break, &vp->scb);
12881291
d_instantiate(op->dentry, inode);

fs/afs/dir_edit.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,3 +556,52 @@ void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_d
556556
0, 0, 0, 0, "..");
557557
goto out;
558558
}
559+
560+
/*
561+
* Initialise a new directory. We need to fill in the "." and ".." entries.
562+
*/
563+
void afs_mkdir_init_dir(struct afs_vnode *dvnode, struct afs_vnode *parent_dvnode)
564+
{
565+
union afs_xdr_dir_block *meta;
566+
struct afs_dir_iter iter = { .dvnode = dvnode };
567+
union afs_xdr_dirent *de;
568+
unsigned int slot = AFS_DIR_RESV_BLOCKS0;
569+
loff_t i_size;
570+
571+
i_size = i_size_read(&dvnode->netfs.inode);
572+
if (i_size != AFS_DIR_BLOCK_SIZE) {
573+
afs_invalidate_dir(dvnode, afs_dir_invalid_edit_add_bad_size);
574+
return;
575+
}
576+
577+
meta = afs_dir_get_block(&iter, 0);
578+
if (!meta)
579+
return;
580+
581+
afs_edit_init_block(meta, meta, 0);
582+
583+
de = &meta->dirents[slot];
584+
de->u.valid = 1;
585+
de->u.vnode = htonl(dvnode->fid.vnode);
586+
de->u.unique = htonl(dvnode->fid.unique);
587+
memcpy(de->u.name, ".", 2);
588+
trace_afs_edit_dir(dvnode, afs_edit_dir_for_mkdir, afs_edit_dir_mkdir, 0, slot,
589+
dvnode->fid.vnode, dvnode->fid.unique, ".");
590+
slot++;
591+
592+
de = &meta->dirents[slot];
593+
de->u.valid = 1;
594+
de->u.vnode = htonl(parent_dvnode->fid.vnode);
595+
de->u.unique = htonl(parent_dvnode->fid.unique);
596+
memcpy(de->u.name, "..", 3);
597+
trace_afs_edit_dir(dvnode, afs_edit_dir_for_mkdir, afs_edit_dir_mkdir, 0, slot,
598+
parent_dvnode->fid.vnode, parent_dvnode->fid.unique, "..");
599+
600+
afs_set_contig_bits(meta, AFS_DIR_RESV_BLOCKS0, 2);
601+
meta->meta.alloc_ctrs[0] -= 2;
602+
kunmap_local(meta);
603+
604+
netfs_single_mark_inode_dirty(&dvnode->netfs.inode);
605+
set_bit(AFS_VNODE_DIR_VALID, &dvnode->flags);
606+
set_bit(AFS_VNODE_DIR_READ, &dvnode->flags);
607+
}

fs/afs/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,7 @@ extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *
10781078
extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason);
10791079
void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode,
10801080
enum afs_edit_dir_reason why);
1081+
void afs_mkdir_init_dir(struct afs_vnode *dvnode, struct afs_vnode *parent_vnode);
10811082

10821083
/*
10831084
* dir_silly.c

include/trace/events/afs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ enum yfs_cm_operation {
350350
EM(afs_dir_invalid_edit_add_no_slots, "edit-add-no-slots") \
351351
EM(afs_dir_invalid_edit_add_too_many_blocks, "edit-add-too-many-blocks") \
352352
EM(afs_dir_invalid_edit_get_block, "edit-get-block") \
353+
EM(afs_dir_invalid_edit_mkdir, "edit-mkdir") \
353354
EM(afs_dir_invalid_edit_rem_bad_size, "edit-rem-bad-size") \
354355
EM(afs_dir_invalid_edit_rem_wrong_name, "edit-rem-wrong_name") \
355356
EM(afs_dir_invalid_edit_upd_bad_size, "edit-upd-bad-size") \
@@ -371,6 +372,7 @@ enum yfs_cm_operation {
371372
EM(afs_edit_dir_delete_error, "d_err ") \
372373
EM(afs_edit_dir_delete_inval, "d_invl") \
373374
EM(afs_edit_dir_delete_noent, "d_nent") \
375+
EM(afs_edit_dir_mkdir, "mk_ent") \
374376
EM(afs_edit_dir_update_dd, "u_ddot") \
375377
EM(afs_edit_dir_update_error, "u_fail") \
376378
EM(afs_edit_dir_update_inval, "u_invl") \

0 commit comments

Comments
 (0)