diff options
Diffstat (limited to 'fs/gfs2/file.c')
-rw-r--r-- | fs/gfs2/file.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 31b199f6efc1..9aa6af13823c 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -142,6 +142,7 @@ static const u32 fsflags_to_gfs2[32] = { | |||
142 | [7] = GFS2_DIF_NOATIME, | 142 | [7] = GFS2_DIF_NOATIME, |
143 | [12] = GFS2_DIF_EXHASH, | 143 | [12] = GFS2_DIF_EXHASH, |
144 | [14] = GFS2_DIF_INHERIT_JDATA, | 144 | [14] = GFS2_DIF_INHERIT_JDATA, |
145 | [17] = GFS2_DIF_TOPDIR, | ||
145 | }; | 146 | }; |
146 | 147 | ||
147 | static const u32 gfs2_to_fsflags[32] = { | 148 | static const u32 gfs2_to_fsflags[32] = { |
@@ -150,6 +151,7 @@ static const u32 gfs2_to_fsflags[32] = { | |||
150 | [gfs2fl_AppendOnly] = FS_APPEND_FL, | 151 | [gfs2fl_AppendOnly] = FS_APPEND_FL, |
151 | [gfs2fl_NoAtime] = FS_NOATIME_FL, | 152 | [gfs2fl_NoAtime] = FS_NOATIME_FL, |
152 | [gfs2fl_ExHash] = FS_INDEX_FL, | 153 | [gfs2fl_ExHash] = FS_INDEX_FL, |
154 | [gfs2fl_TopLevel] = FS_TOPDIR_FL, | ||
153 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, | 155 | [gfs2fl_InheritJdata] = FS_JOURNAL_DATA_FL, |
154 | }; | 156 | }; |
155 | 157 | ||
@@ -203,6 +205,7 @@ void gfs2_set_inode_flags(struct inode *inode) | |||
203 | GFS2_DIF_NOATIME| \ | 205 | GFS2_DIF_NOATIME| \ |
204 | GFS2_DIF_SYNC| \ | 206 | GFS2_DIF_SYNC| \ |
205 | GFS2_DIF_SYSTEM| \ | 207 | GFS2_DIF_SYSTEM| \ |
208 | GFS2_DIF_TOPDIR| \ | ||
206 | GFS2_DIF_INHERIT_JDATA) | 209 | GFS2_DIF_INHERIT_JDATA) |
207 | 210 | ||
208 | /** | 211 | /** |
@@ -298,6 +301,7 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr) | |||
298 | 301 | ||
299 | gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); | 302 | gfsflags = fsflags_cvt(fsflags_to_gfs2, fsflags); |
300 | if (!S_ISDIR(inode->i_mode)) { | 303 | if (!S_ISDIR(inode->i_mode)) { |
304 | gfsflags &= ~GFS2_DIF_TOPDIR; | ||
301 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) | 305 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) |
302 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); | 306 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); |
303 | return do_gfs2_set_flags(filp, gfsflags, ~0); | 307 | return do_gfs2_set_flags(filp, gfsflags, ~0); |
@@ -366,7 +370,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
366 | u64 pos = page->index << PAGE_CACHE_SHIFT; | 370 | u64 pos = page->index << PAGE_CACHE_SHIFT; |
367 | unsigned int data_blocks, ind_blocks, rblocks; | 371 | unsigned int data_blocks, ind_blocks, rblocks; |
368 | struct gfs2_holder gh; | 372 | struct gfs2_holder gh; |
369 | struct gfs2_qadata *qa; | ||
370 | loff_t size; | 373 | loff_t size; |
371 | int ret; | 374 | int ret; |
372 | 375 | ||
@@ -376,6 +379,13 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
376 | */ | 379 | */ |
377 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); | 380 | vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); |
378 | 381 | ||
382 | ret = gfs2_rs_alloc(ip); | ||
383 | if (ret) | ||
384 | return ret; | ||
385 | |||
386 | atomic_set(&ip->i_res->rs_sizehint, | ||
387 | PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift); | ||
388 | |||
379 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 389 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
380 | ret = gfs2_glock_nq(&gh); | 390 | ret = gfs2_glock_nq(&gh); |
381 | if (ret) | 391 | if (ret) |
@@ -393,14 +403,13 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
393 | goto out_unlock; | 403 | goto out_unlock; |
394 | } | 404 | } |
395 | 405 | ||
396 | ret = -ENOMEM; | 406 | ret = gfs2_rindex_update(sdp); |
397 | qa = gfs2_qadata_get(ip); | 407 | if (ret) |
398 | if (qa == NULL) | ||
399 | goto out_unlock; | 408 | goto out_unlock; |
400 | 409 | ||
401 | ret = gfs2_quota_lock_check(ip); | 410 | ret = gfs2_quota_lock_check(ip); |
402 | if (ret) | 411 | if (ret) |
403 | goto out_alloc_put; | 412 | goto out_unlock; |
404 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); | 413 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); |
405 | ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); | 414 | ret = gfs2_inplace_reserve(ip, data_blocks + ind_blocks); |
406 | if (ret) | 415 | if (ret) |
@@ -447,8 +456,6 @@ out_trans_fail: | |||
447 | gfs2_inplace_release(ip); | 456 | gfs2_inplace_release(ip); |
448 | out_quota_unlock: | 457 | out_quota_unlock: |
449 | gfs2_quota_unlock(ip); | 458 | gfs2_quota_unlock(ip); |
450 | out_alloc_put: | ||
451 | gfs2_qadata_put(ip); | ||
452 | out_unlock: | 459 | out_unlock: |
453 | gfs2_glock_dq(&gh); | 460 | gfs2_glock_dq(&gh); |
454 | out: | 461 | out: |
@@ -567,16 +574,14 @@ fail: | |||
567 | 574 | ||
568 | static int gfs2_release(struct inode *inode, struct file *file) | 575 | static int gfs2_release(struct inode *inode, struct file *file) |
569 | { | 576 | { |
570 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | 577 | struct gfs2_inode *ip = GFS2_I(inode); |
571 | struct gfs2_file *fp; | ||
572 | 578 | ||
573 | fp = file->private_data; | 579 | kfree(file->private_data); |
574 | file->private_data = NULL; | 580 | file->private_data = NULL; |
575 | 581 | ||
576 | if (gfs2_assert_warn(sdp, fp)) | 582 | if ((file->f_mode & FMODE_WRITE) && |
577 | return -EIO; | 583 | (atomic_read(&inode->i_writecount) == 1)) |
578 | 584 | gfs2_rs_delete(ip); | |
579 | kfree(fp); | ||
580 | 585 | ||
581 | return 0; | 586 | return 0; |
582 | } | 587 | } |
@@ -653,12 +658,20 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
653 | unsigned long nr_segs, loff_t pos) | 658 | unsigned long nr_segs, loff_t pos) |
654 | { | 659 | { |
655 | struct file *file = iocb->ki_filp; | 660 | struct file *file = iocb->ki_filp; |
661 | size_t writesize = iov_length(iov, nr_segs); | ||
662 | struct dentry *dentry = file->f_dentry; | ||
663 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
664 | struct gfs2_sbd *sdp; | ||
665 | int ret; | ||
656 | 666 | ||
667 | sdp = GFS2_SB(file->f_mapping->host); | ||
668 | ret = gfs2_rs_alloc(ip); | ||
669 | if (ret) | ||
670 | return ret; | ||
671 | |||
672 | atomic_set(&ip->i_res->rs_sizehint, writesize >> sdp->sd_sb.sb_bsize_shift); | ||
657 | if (file->f_flags & O_APPEND) { | 673 | if (file->f_flags & O_APPEND) { |
658 | struct dentry *dentry = file->f_dentry; | ||
659 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
660 | struct gfs2_holder gh; | 674 | struct gfs2_holder gh; |
661 | int ret; | ||
662 | 675 | ||
663 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | 676 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); |
664 | if (ret) | 677 | if (ret) |
@@ -751,7 +764,6 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
751 | struct gfs2_inode *ip = GFS2_I(inode); | 764 | struct gfs2_inode *ip = GFS2_I(inode); |
752 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; | 765 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; |
753 | loff_t bytes, max_bytes; | 766 | loff_t bytes, max_bytes; |
754 | struct gfs2_qadata *qa; | ||
755 | int error; | 767 | int error; |
756 | const loff_t pos = offset; | 768 | const loff_t pos = offset; |
757 | const loff_t count = len; | 769 | const loff_t count = len; |
@@ -774,11 +786,17 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
774 | if (bytes == 0) | 786 | if (bytes == 0) |
775 | bytes = sdp->sd_sb.sb_bsize; | 787 | bytes = sdp->sd_sb.sb_bsize; |
776 | 788 | ||
789 | error = gfs2_rs_alloc(ip); | ||
790 | if (error) | ||
791 | return error; | ||
792 | |||
777 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); | 793 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); |
778 | error = gfs2_glock_nq(&ip->i_gh); | 794 | error = gfs2_glock_nq(&ip->i_gh); |
779 | if (unlikely(error)) | 795 | if (unlikely(error)) |
780 | goto out_uninit; | 796 | goto out_uninit; |
781 | 797 | ||
798 | atomic_set(&ip->i_res->rs_sizehint, len >> sdp->sd_sb.sb_bsize_shift); | ||
799 | |||
782 | while (len > 0) { | 800 | while (len > 0) { |
783 | if (len < bytes) | 801 | if (len < bytes) |
784 | bytes = len; | 802 | bytes = len; |
@@ -787,15 +805,9 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
787 | offset += bytes; | 805 | offset += bytes; |
788 | continue; | 806 | continue; |
789 | } | 807 | } |
790 | qa = gfs2_qadata_get(ip); | ||
791 | if (!qa) { | ||
792 | error = -ENOMEM; | ||
793 | goto out_unlock; | ||
794 | } | ||
795 | |||
796 | error = gfs2_quota_lock_check(ip); | 808 | error = gfs2_quota_lock_check(ip); |
797 | if (error) | 809 | if (error) |
798 | goto out_alloc_put; | 810 | goto out_unlock; |
799 | 811 | ||
800 | retry: | 812 | retry: |
801 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); | 813 | gfs2_write_calc_reserv(ip, bytes, &data_blocks, &ind_blocks); |
@@ -835,7 +847,6 @@ retry: | |||
835 | offset += max_bytes; | 847 | offset += max_bytes; |
836 | gfs2_inplace_release(ip); | 848 | gfs2_inplace_release(ip); |
837 | gfs2_quota_unlock(ip); | 849 | gfs2_quota_unlock(ip); |
838 | gfs2_qadata_put(ip); | ||
839 | } | 850 | } |
840 | 851 | ||
841 | if (error == 0) | 852 | if (error == 0) |
@@ -846,8 +857,6 @@ out_trans_fail: | |||
846 | gfs2_inplace_release(ip); | 857 | gfs2_inplace_release(ip); |
847 | out_qunlock: | 858 | out_qunlock: |
848 | gfs2_quota_unlock(ip); | 859 | gfs2_quota_unlock(ip); |
849 | out_alloc_put: | ||
850 | gfs2_qadata_put(ip); | ||
851 | out_unlock: | 860 | out_unlock: |
852 | gfs2_glock_dq(&ip->i_gh); | 861 | gfs2_glock_dq(&ip->i_gh); |
853 | out_uninit: | 862 | out_uninit: |