aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2014-02-04 10:45:11 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2014-02-04 10:45:11 -0500
commitb2c8b3ea871e478ac144f617d015d3aa55fc3aa8 (patch)
tree85d094c3125b147bfddbb6e509fd9c238e1125f6 /fs/gfs2
parent885bceca7ff12021c9c17f58d12e12ec6e8e59a6 (diff)
GFS2: Allocate block for xattr at inode alloc time, if required
This is another step towards improving the allocation of xattr blocks at inode allocation time. Here we take advantage of Christoph's recent work on ACLs to allocate a block for the xattrs early if we know that we will be adding ACLs to the inode later on. The advantage of that is that it is much more likely that we'll get a contiguous run of two blocks where the first is the inode and the second is the xattr block. We still have to fall back to the original system in case we don't get the requested two contiguous blocks, or in case the ACLs are too large to fit into the block. Future patches will move more of the ACL setting code further up the gfs2_inode_create() function. Also, I'd like to be able to do the same thing with the xattrs from LSMs in due course, too. That way we should be able to slowly reduce the number of independent transactions, at least in the most common cases. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/inode.c50
-rw-r--r--fs/gfs2/rgrp.c2
2 files changed, 44 insertions, 8 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 5c524180c98e..ec455b92091f 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -376,12 +376,11 @@ static void munge_mode_uid_gid(const struct gfs2_inode *dip,
376 inode->i_gid = current_fsgid(); 376 inode->i_gid = current_fsgid();
377} 377}
378 378
379static int alloc_dinode(struct gfs2_inode *ip, u32 flags) 379static int alloc_dinode(struct gfs2_inode *ip, u32 flags, unsigned *dblocks)
380{ 380{
381 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 381 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
382 struct gfs2_alloc_parms ap = { .target = RES_DINODE, .aflags = flags, }; 382 struct gfs2_alloc_parms ap = { .target = *dblocks, .aflags = flags, };
383 int error; 383 int error;
384 int dblocks = 1;
385 384
386 error = gfs2_quota_lock_check(ip); 385 error = gfs2_quota_lock_check(ip);
387 if (error) 386 if (error)
@@ -391,11 +390,11 @@ static int alloc_dinode(struct gfs2_inode *ip, u32 flags)
391 if (error) 390 if (error)
392 goto out_quota; 391 goto out_quota;
393 392
394 error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 0); 393 error = gfs2_trans_begin(sdp, (*dblocks * RES_RG_BIT) + RES_STATFS + RES_QUOTA, 0);
395 if (error) 394 if (error)
396 goto out_ipreserv; 395 goto out_ipreserv;
397 396
398 error = gfs2_alloc_blocks(ip, &ip->i_no_addr, &dblocks, 1, &ip->i_generation); 397 error = gfs2_alloc_blocks(ip, &ip->i_no_addr, dblocks, 1, &ip->i_generation);
399 ip->i_no_formal_ino = ip->i_generation; 398 ip->i_no_formal_ino = ip->i_generation;
400 ip->i_inode.i_ino = ip->i_no_addr; 399 ip->i_inode.i_ino = ip->i_no_addr;
401 ip->i_goal = ip->i_no_addr; 400 ip->i_goal = ip->i_no_addr;
@@ -428,6 +427,33 @@ static void gfs2_init_dir(struct buffer_head *dibh,
428} 427}
429 428
430/** 429/**
430 * gfs2_init_xattr - Initialise an xattr block for a new inode
431 * @ip: The inode in question
432 *
433 * This sets up an empty xattr block for a new inode, ready to
434 * take any ACLs, LSM xattrs, etc.
435 */
436
437static void gfs2_init_xattr(struct gfs2_inode *ip)
438{
439 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
440 struct buffer_head *bh;
441 struct gfs2_ea_header *ea;
442
443 bh = gfs2_meta_new(ip->i_gl, ip->i_eattr);
444 gfs2_trans_add_meta(ip->i_gl, bh);
445 gfs2_metatype_set(bh, GFS2_METATYPE_EA, GFS2_FORMAT_EA);
446 gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
447
448 ea = GFS2_EA_BH2FIRST(bh);
449 ea->ea_rec_len = cpu_to_be32(sdp->sd_jbsize);
450 ea->ea_type = GFS2_EATYPE_UNUSED;
451 ea->ea_flags = GFS2_EAFLAG_LAST;
452
453 brelse(bh);
454}
455
456/**
431 * init_dinode - Fill in a new dinode structure 457 * init_dinode - Fill in a new dinode structure
432 * @dip: The directory this inode is being created in 458 * @dip: The directory this inode is being created in
433 * @ip: The inode 459 * @ip: The inode
@@ -580,6 +606,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
580 struct dentry *d; 606 struct dentry *d;
581 int error; 607 int error;
582 u32 aflags = 0; 608 u32 aflags = 0;
609 unsigned blocks = 1;
583 struct gfs2_diradd da = { .bh = NULL, }; 610 struct gfs2_diradd da = { .bh = NULL, };
584 611
585 if (!name->len || name->len > GFS2_FNAMESIZE) 612 if (!name->len || name->len > GFS2_FNAMESIZE)
@@ -676,10 +703,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
676 (dip->i_diskflags & GFS2_DIF_TOPDIR)) 703 (dip->i_diskflags & GFS2_DIF_TOPDIR))
677 aflags |= GFS2_AF_ORLOV; 704 aflags |= GFS2_AF_ORLOV;
678 705
679 error = alloc_dinode(ip, aflags); 706 if (default_acl || acl)
707 blocks++;
708
709 error = alloc_dinode(ip, aflags, &blocks);
680 if (error) 710 if (error)
681 goto fail_free_inode; 711 goto fail_free_inode;
682 712
713 gfs2_set_inode_blocks(inode, blocks);
714
683 error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); 715 error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
684 if (error) 716 if (error)
685 goto fail_free_inode; 717 goto fail_free_inode;
@@ -689,10 +721,14 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
689 if (error) 721 if (error)
690 goto fail_free_inode; 722 goto fail_free_inode;
691 723
692 error = gfs2_trans_begin(sdp, RES_DINODE, 0); 724 error = gfs2_trans_begin(sdp, blocks, 0);
693 if (error) 725 if (error)
694 goto fail_gunlock2; 726 goto fail_gunlock2;
695 727
728 if (blocks > 1) {
729 ip->i_eattr = ip->i_no_addr + 1;
730 gfs2_init_xattr(ip);
731 }
696 init_dinode(dip, ip, symname); 732 init_dinode(dip, ip, symname);
697 gfs2_trans_end(sdp); 733 gfs2_trans_end(sdp);
698 734
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index a1da21349235..c13e4c5e9967 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -2296,7 +2296,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
2296 2296
2297 gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0); 2297 gfs2_statfs_change(sdp, 0, -(s64)*nblocks, dinode ? 1 : 0);
2298 if (dinode) 2298 if (dinode)
2299 gfs2_trans_add_unrevoke(sdp, block, 1); 2299 gfs2_trans_add_unrevoke(sdp, block, *nblocks);
2300 2300
2301 gfs2_quota_change(ip, *nblocks, ip->i_inode.i_uid, ip->i_inode.i_gid); 2301 gfs2_quota_change(ip, *nblocks, ip->i_inode.i_uid, ip->i_inode.i_gid);
2302 2302