diff options
-rw-r--r-- | fs/gfs2/inode.c | 50 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 2 | ||||
-rw-r--r-- | include/uapi/linux/gfs2_ondisk.h | 4 |
3 files changed, 46 insertions, 10 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 | ||
379 | static int alloc_dinode(struct gfs2_inode *ip, u32 flags) | 379 | static 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 | |||
437 | static 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 | ||
diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index 0f24c07aed51..310020816809 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h | |||
@@ -347,9 +347,9 @@ struct gfs2_leaf { | |||
347 | * metadata header. Each inode, if it has extended attributes, will | 347 | * metadata header. Each inode, if it has extended attributes, will |
348 | * have either a single block containing the extended attribute headers | 348 | * have either a single block containing the extended attribute headers |
349 | * or a single indirect block pointing to blocks containing the | 349 | * or a single indirect block pointing to blocks containing the |
350 | * extended attribure headers. | 350 | * extended attribute headers. |
351 | * | 351 | * |
352 | * The maximim size of the data part of an extended attribute is 64k | 352 | * The maximum size of the data part of an extended attribute is 64k |
353 | * so the number of blocks required depends upon block size. Since the | 353 | * so the number of blocks required depends upon block size. Since the |
354 | * block size also determines the number of pointers in an indirect | 354 | * block size also determines the number of pointers in an indirect |
355 | * block, its a fairly complicated calculation to work out the maximum | 355 | * block, its a fairly complicated calculation to work out the maximum |