diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 16:28:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-20 16:28:45 -0400 |
commit | 6c1b8d94bcc1882e451d0e7a28a4a5253f4970ab (patch) | |
tree | 1e612ce2e7b5e2164ffa49ad6518ca2834a7f9bb /fs/gfs2 | |
parent | 82aff107f8c9194586f68e86412246629d05670a (diff) | |
parent | f2741d9898269e565c220ec295a8f5c3756c7585 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw: (32 commits)
GFS2: Move all locking inside the inode creation function
GFS2: Clean up symlink creation
GFS2: Clean up mkdir
GFS2: Use UUID field in generic superblock
GFS2: Rename ops_inode.c to inode.c
GFS2: Inode.c is empty now, remove it
GFS2: Move final part of inode.c into super.c
GFS2: Move most of the remaining inode.c into ops_inode.c
GFS2: Move gfs2_refresh_inode() and friends into glops.c
GFS2: Remove gfs2_dinode_print() function
GFS2: When adding a new dir entry, inc link count if it is a subdir
GFS2: Make gfs2_dir_del update link count when required
GFS2: Don't use gfs2_change_nlink in link syscall
GFS2: Don't use a try lock when promoting to a higher mode
GFS2: Double check link count under glock
GFS2: Improve bug trap code in ->releasepage()
GFS2: Fix ail list traversal
GFS2: make sure fallocate bytes is a multiple of blksize
GFS2: Add an AIL writeback tracepoint
GFS2: Make writeback more responsive to system conditions
...
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/Makefile | 4 | ||||
-rw-r--r-- | fs/gfs2/aops.c | 8 | ||||
-rw-r--r-- | fs/gfs2/dir.c | 197 | ||||
-rw-r--r-- | fs/gfs2/dir.h | 4 | ||||
-rw-r--r-- | fs/gfs2/export.c | 2 | ||||
-rw-r--r-- | fs/gfs2/file.c | 46 | ||||
-rw-r--r-- | fs/gfs2/glock.c | 94 | ||||
-rw-r--r-- | fs/gfs2/glock.h | 3 | ||||
-rw-r--r-- | fs/gfs2/glops.c | 172 | ||||
-rw-r--r-- | fs/gfs2/glops.h | 2 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 8 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 1510 | ||||
-rw-r--r-- | fs/gfs2/inode.h | 8 | ||||
-rw-r--r-- | fs/gfs2/log.c | 179 | ||||
-rw-r--r-- | fs/gfs2/log.h | 2 | ||||
-rw-r--r-- | fs/gfs2/lops.c | 39 | ||||
-rw-r--r-- | fs/gfs2/main.c | 1 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 2 | ||||
-rw-r--r-- | fs/gfs2/meta_io.h | 2 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 32 | ||||
-rw-r--r-- | fs/gfs2/ops_inode.c | 1344 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 20 | ||||
-rw-r--r-- | fs/gfs2/super.c | 138 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 6 | ||||
-rw-r--r-- | fs/gfs2/trace_gfs2.h | 38 |
25 files changed, 1847 insertions, 2014 deletions
diff --git a/fs/gfs2/Makefile b/fs/gfs2/Makefile index f3d23ef4e876..86128202384f 100644 --- a/fs/gfs2/Makefile +++ b/fs/gfs2/Makefile | |||
@@ -1,9 +1,9 @@ | |||
1 | ccflags-y := -I$(src) | 1 | ccflags-y := -I$(src) |
2 | obj-$(CONFIG_GFS2_FS) += gfs2.o | 2 | obj-$(CONFIG_GFS2_FS) += gfs2.o |
3 | gfs2-y := acl.o bmap.o dir.o xattr.o glock.o \ | 3 | gfs2-y := acl.o bmap.o dir.o xattr.o glock.o \ |
4 | glops.o inode.o log.o lops.o main.o meta_io.o \ | 4 | glops.o log.o lops.o main.o meta_io.o \ |
5 | aops.o dentry.o export.o file.o \ | 5 | aops.o dentry.o export.o file.o \ |
6 | ops_fstype.o ops_inode.o quota.o \ | 6 | ops_fstype.o inode.o quota.o \ |
7 | recovery.o rgrp.o super.o sys.o trans.o util.o | 7 | recovery.o rgrp.o super.o sys.o trans.o util.o |
8 | 8 | ||
9 | gfs2-$(CONFIG_GFS2_FS_LOCKING_DLM) += lock_dlm.o | 9 | gfs2-$(CONFIG_GFS2_FS_LOCKING_DLM) += lock_dlm.o |
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 0f5c4f9d5d62..802ac5eeba28 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -1076,8 +1076,8 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1076 | bd = bh->b_private; | 1076 | bd = bh->b_private; |
1077 | if (bd && bd->bd_ail) | 1077 | if (bd && bd->bd_ail) |
1078 | goto cannot_release; | 1078 | goto cannot_release; |
1079 | gfs2_assert_warn(sdp, !buffer_pinned(bh)); | 1079 | if (buffer_pinned(bh) || buffer_dirty(bh)) |
1080 | gfs2_assert_warn(sdp, !buffer_dirty(bh)); | 1080 | goto not_possible; |
1081 | bh = bh->b_this_page; | 1081 | bh = bh->b_this_page; |
1082 | } while(bh != head); | 1082 | } while(bh != head); |
1083 | gfs2_log_unlock(sdp); | 1083 | gfs2_log_unlock(sdp); |
@@ -1107,6 +1107,10 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1107 | } while (bh != head); | 1107 | } while (bh != head); |
1108 | 1108 | ||
1109 | return try_to_free_buffers(page); | 1109 | return try_to_free_buffers(page); |
1110 | |||
1111 | not_possible: /* Should never happen */ | ||
1112 | WARN_ON(buffer_dirty(bh)); | ||
1113 | WARN_ON(buffer_pinned(bh)); | ||
1110 | cannot_release: | 1114 | cannot_release: |
1111 | gfs2_log_unlock(sdp); | 1115 | gfs2_log_unlock(sdp); |
1112 | return 0; | 1116 | return 0; |
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index f789c5732b7c..091ee4779538 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -82,12 +82,9 @@ | |||
82 | struct qstr gfs2_qdot __read_mostly; | 82 | struct qstr gfs2_qdot __read_mostly; |
83 | struct qstr gfs2_qdotdot __read_mostly; | 83 | struct qstr gfs2_qdotdot __read_mostly; |
84 | 84 | ||
85 | typedef int (*leaf_call_t) (struct gfs2_inode *dip, u32 index, u32 len, | ||
86 | u64 leaf_no, void *data); | ||
87 | typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent, | 85 | typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent, |
88 | const struct qstr *name, void *opaque); | 86 | const struct qstr *name, void *opaque); |
89 | 87 | ||
90 | |||
91 | int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block, | 88 | int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block, |
92 | struct buffer_head **bhp) | 89 | struct buffer_head **bhp) |
93 | { | 90 | { |
@@ -1600,7 +1597,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1600 | */ | 1597 | */ |
1601 | 1598 | ||
1602 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, | 1599 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, |
1603 | const struct gfs2_inode *nip, unsigned type) | 1600 | const struct gfs2_inode *nip) |
1604 | { | 1601 | { |
1605 | struct gfs2_inode *ip = GFS2_I(inode); | 1602 | struct gfs2_inode *ip = GFS2_I(inode); |
1606 | struct buffer_head *bh; | 1603 | struct buffer_head *bh; |
@@ -1616,7 +1613,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1616 | return PTR_ERR(dent); | 1613 | return PTR_ERR(dent); |
1617 | dent = gfs2_init_dirent(inode, dent, name, bh); | 1614 | dent = gfs2_init_dirent(inode, dent, name, bh); |
1618 | gfs2_inum_out(nip, dent); | 1615 | gfs2_inum_out(nip, dent); |
1619 | dent->de_type = cpu_to_be16(type); | 1616 | dent->de_type = cpu_to_be16(IF2DT(nip->i_inode.i_mode)); |
1620 | if (ip->i_diskflags & GFS2_DIF_EXHASH) { | 1617 | if (ip->i_diskflags & GFS2_DIF_EXHASH) { |
1621 | leaf = (struct gfs2_leaf *)bh->b_data; | 1618 | leaf = (struct gfs2_leaf *)bh->b_data; |
1622 | be16_add_cpu(&leaf->lf_entries, 1); | 1619 | be16_add_cpu(&leaf->lf_entries, 1); |
@@ -1628,6 +1625,8 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1628 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1625 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1629 | ip->i_entries++; | 1626 | ip->i_entries++; |
1630 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 1627 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
1628 | if (S_ISDIR(nip->i_inode.i_mode)) | ||
1629 | inc_nlink(&ip->i_inode); | ||
1631 | gfs2_dinode_out(ip, bh->b_data); | 1630 | gfs2_dinode_out(ip, bh->b_data); |
1632 | brelse(bh); | 1631 | brelse(bh); |
1633 | error = 0; | 1632 | error = 0; |
@@ -1672,8 +1671,9 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1672 | * Returns: 0 on success, error code on failure | 1671 | * Returns: 0 on success, error code on failure |
1673 | */ | 1672 | */ |
1674 | 1673 | ||
1675 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | 1674 | int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry) |
1676 | { | 1675 | { |
1676 | const struct qstr *name = &dentry->d_name; | ||
1677 | struct gfs2_dirent *dent, *prev = NULL; | 1677 | struct gfs2_dirent *dent, *prev = NULL; |
1678 | struct buffer_head *bh; | 1678 | struct buffer_head *bh; |
1679 | int error; | 1679 | int error; |
@@ -1714,6 +1714,8 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1714 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1714 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1715 | dip->i_entries--; | 1715 | dip->i_entries--; |
1716 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; | 1716 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; |
1717 | if (S_ISDIR(dentry->d_inode->i_mode)) | ||
1718 | drop_nlink(&dip->i_inode); | ||
1717 | gfs2_dinode_out(dip, bh->b_data); | 1719 | gfs2_dinode_out(dip, bh->b_data); |
1718 | brelse(bh); | 1720 | brelse(bh); |
1719 | mark_inode_dirty(&dip->i_inode); | 1721 | mark_inode_dirty(&dip->i_inode); |
@@ -1768,94 +1770,20 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | |||
1768 | } | 1770 | } |
1769 | 1771 | ||
1770 | /** | 1772 | /** |
1771 | * foreach_leaf - call a function for each leaf in a directory | ||
1772 | * @dip: the directory | ||
1773 | * @lc: the function to call for each each | ||
1774 | * @data: private data to pass to it | ||
1775 | * | ||
1776 | * Returns: errno | ||
1777 | */ | ||
1778 | |||
1779 | static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | ||
1780 | { | ||
1781 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
1782 | struct buffer_head *bh; | ||
1783 | struct gfs2_leaf *leaf; | ||
1784 | u32 hsize, len; | ||
1785 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | ||
1786 | u32 index = 0; | ||
1787 | __be64 *lp; | ||
1788 | u64 leaf_no; | ||
1789 | int error = 0; | ||
1790 | |||
1791 | hsize = 1 << dip->i_depth; | ||
1792 | if (hsize * sizeof(u64) != i_size_read(&dip->i_inode)) { | ||
1793 | gfs2_consist_inode(dip); | ||
1794 | return -EIO; | ||
1795 | } | ||
1796 | |||
1797 | lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS); | ||
1798 | if (!lp) | ||
1799 | return -ENOMEM; | ||
1800 | |||
1801 | while (index < hsize) { | ||
1802 | lp_offset = index & (sdp->sd_hash_ptrs - 1); | ||
1803 | ht_offset = index - lp_offset; | ||
1804 | |||
1805 | if (ht_offset_cur != ht_offset) { | ||
1806 | error = gfs2_dir_read_data(dip, (char *)lp, | ||
1807 | ht_offset * sizeof(__be64), | ||
1808 | sdp->sd_hash_bsize, 1); | ||
1809 | if (error != sdp->sd_hash_bsize) { | ||
1810 | if (error >= 0) | ||
1811 | error = -EIO; | ||
1812 | goto out; | ||
1813 | } | ||
1814 | ht_offset_cur = ht_offset; | ||
1815 | } | ||
1816 | |||
1817 | leaf_no = be64_to_cpu(lp[lp_offset]); | ||
1818 | if (leaf_no) { | ||
1819 | error = get_leaf(dip, leaf_no, &bh); | ||
1820 | if (error) | ||
1821 | goto out; | ||
1822 | leaf = (struct gfs2_leaf *)bh->b_data; | ||
1823 | len = 1 << (dip->i_depth - be16_to_cpu(leaf->lf_depth)); | ||
1824 | brelse(bh); | ||
1825 | |||
1826 | error = lc(dip, index, len, leaf_no, data); | ||
1827 | if (error) | ||
1828 | goto out; | ||
1829 | |||
1830 | index = (index & ~(len - 1)) + len; | ||
1831 | } else | ||
1832 | index++; | ||
1833 | } | ||
1834 | |||
1835 | if (index != hsize) { | ||
1836 | gfs2_consist_inode(dip); | ||
1837 | error = -EIO; | ||
1838 | } | ||
1839 | |||
1840 | out: | ||
1841 | kfree(lp); | ||
1842 | |||
1843 | return error; | ||
1844 | } | ||
1845 | |||
1846 | /** | ||
1847 | * leaf_dealloc - Deallocate a directory leaf | 1773 | * leaf_dealloc - Deallocate a directory leaf |
1848 | * @dip: the directory | 1774 | * @dip: the directory |
1849 | * @index: the hash table offset in the directory | 1775 | * @index: the hash table offset in the directory |
1850 | * @len: the number of pointers to this leaf | 1776 | * @len: the number of pointers to this leaf |
1851 | * @leaf_no: the leaf number | 1777 | * @leaf_no: the leaf number |
1852 | * @data: not used | 1778 | * @leaf_bh: buffer_head for the starting leaf |
1779 | * last_dealloc: 1 if this is the final dealloc for the leaf, else 0 | ||
1853 | * | 1780 | * |
1854 | * Returns: errno | 1781 | * Returns: errno |
1855 | */ | 1782 | */ |
1856 | 1783 | ||
1857 | static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | 1784 | static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, |
1858 | u64 leaf_no, void *data) | 1785 | u64 leaf_no, struct buffer_head *leaf_bh, |
1786 | int last_dealloc) | ||
1859 | { | 1787 | { |
1860 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 1788 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
1861 | struct gfs2_leaf *tmp_leaf; | 1789 | struct gfs2_leaf *tmp_leaf; |
@@ -1887,14 +1815,18 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1887 | goto out_qs; | 1815 | goto out_qs; |
1888 | 1816 | ||
1889 | /* Count the number of leaves */ | 1817 | /* Count the number of leaves */ |
1818 | bh = leaf_bh; | ||
1890 | 1819 | ||
1891 | for (blk = leaf_no; blk; blk = nblk) { | 1820 | for (blk = leaf_no; blk; blk = nblk) { |
1892 | error = get_leaf(dip, blk, &bh); | 1821 | if (blk != leaf_no) { |
1893 | if (error) | 1822 | error = get_leaf(dip, blk, &bh); |
1894 | goto out_rlist; | 1823 | if (error) |
1824 | goto out_rlist; | ||
1825 | } | ||
1895 | tmp_leaf = (struct gfs2_leaf *)bh->b_data; | 1826 | tmp_leaf = (struct gfs2_leaf *)bh->b_data; |
1896 | nblk = be64_to_cpu(tmp_leaf->lf_next); | 1827 | nblk = be64_to_cpu(tmp_leaf->lf_next); |
1897 | brelse(bh); | 1828 | if (blk != leaf_no) |
1829 | brelse(bh); | ||
1898 | 1830 | ||
1899 | gfs2_rlist_add(sdp, &rlist, blk); | 1831 | gfs2_rlist_add(sdp, &rlist, blk); |
1900 | l_blocks++; | 1832 | l_blocks++; |
@@ -1918,13 +1850,18 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1918 | if (error) | 1850 | if (error) |
1919 | goto out_rg_gunlock; | 1851 | goto out_rg_gunlock; |
1920 | 1852 | ||
1853 | bh = leaf_bh; | ||
1854 | |||
1921 | for (blk = leaf_no; blk; blk = nblk) { | 1855 | for (blk = leaf_no; blk; blk = nblk) { |
1922 | error = get_leaf(dip, blk, &bh); | 1856 | if (blk != leaf_no) { |
1923 | if (error) | 1857 | error = get_leaf(dip, blk, &bh); |
1924 | goto out_end_trans; | 1858 | if (error) |
1859 | goto out_end_trans; | ||
1860 | } | ||
1925 | tmp_leaf = (struct gfs2_leaf *)bh->b_data; | 1861 | tmp_leaf = (struct gfs2_leaf *)bh->b_data; |
1926 | nblk = be64_to_cpu(tmp_leaf->lf_next); | 1862 | nblk = be64_to_cpu(tmp_leaf->lf_next); |
1927 | brelse(bh); | 1863 | if (blk != leaf_no) |
1864 | brelse(bh); | ||
1928 | 1865 | ||
1929 | gfs2_free_meta(dip, blk, 1); | 1866 | gfs2_free_meta(dip, blk, 1); |
1930 | gfs2_add_inode_blocks(&dip->i_inode, -1); | 1867 | gfs2_add_inode_blocks(&dip->i_inode, -1); |
@@ -1942,6 +1879,10 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1942 | goto out_end_trans; | 1879 | goto out_end_trans; |
1943 | 1880 | ||
1944 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); | 1881 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); |
1882 | /* On the last dealloc, make this a regular file in case we crash. | ||
1883 | (We don't want to free these blocks a second time.) */ | ||
1884 | if (last_dealloc) | ||
1885 | dip->i_inode.i_mode = S_IFREG; | ||
1945 | gfs2_dinode_out(dip, dibh->b_data); | 1886 | gfs2_dinode_out(dip, dibh->b_data); |
1946 | brelse(dibh); | 1887 | brelse(dibh); |
1947 | 1888 | ||
@@ -1975,29 +1916,67 @@ int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip) | |||
1975 | { | 1916 | { |
1976 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 1917 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
1977 | struct buffer_head *bh; | 1918 | struct buffer_head *bh; |
1978 | int error; | 1919 | struct gfs2_leaf *leaf; |
1920 | u32 hsize, len; | ||
1921 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | ||
1922 | u32 index = 0, next_index; | ||
1923 | __be64 *lp; | ||
1924 | u64 leaf_no; | ||
1925 | int error = 0, last; | ||
1979 | 1926 | ||
1980 | /* Dealloc on-disk leaves to FREEMETA state */ | 1927 | hsize = 1 << dip->i_depth; |
1981 | error = foreach_leaf(dip, leaf_dealloc, NULL); | 1928 | if (hsize * sizeof(u64) != i_size_read(&dip->i_inode)) { |
1982 | if (error) | 1929 | gfs2_consist_inode(dip); |
1983 | return error; | 1930 | return -EIO; |
1931 | } | ||
1984 | 1932 | ||
1985 | /* Make this a regular file in case we crash. | 1933 | lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS); |
1986 | (We don't want to free these blocks a second time.) */ | 1934 | if (!lp) |
1935 | return -ENOMEM; | ||
1987 | 1936 | ||
1988 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 1937 | while (index < hsize) { |
1989 | if (error) | 1938 | lp_offset = index & (sdp->sd_hash_ptrs - 1); |
1990 | return error; | 1939 | ht_offset = index - lp_offset; |
1991 | 1940 | ||
1992 | error = gfs2_meta_inode_buffer(dip, &bh); | 1941 | if (ht_offset_cur != ht_offset) { |
1993 | if (!error) { | 1942 | error = gfs2_dir_read_data(dip, (char *)lp, |
1994 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1943 | ht_offset * sizeof(__be64), |
1995 | ((struct gfs2_dinode *)bh->b_data)->di_mode = | 1944 | sdp->sd_hash_bsize, 1); |
1996 | cpu_to_be32(S_IFREG); | 1945 | if (error != sdp->sd_hash_bsize) { |
1997 | brelse(bh); | 1946 | if (error >= 0) |
1947 | error = -EIO; | ||
1948 | goto out; | ||
1949 | } | ||
1950 | ht_offset_cur = ht_offset; | ||
1951 | } | ||
1952 | |||
1953 | leaf_no = be64_to_cpu(lp[lp_offset]); | ||
1954 | if (leaf_no) { | ||
1955 | error = get_leaf(dip, leaf_no, &bh); | ||
1956 | if (error) | ||
1957 | goto out; | ||
1958 | leaf = (struct gfs2_leaf *)bh->b_data; | ||
1959 | len = 1 << (dip->i_depth - be16_to_cpu(leaf->lf_depth)); | ||
1960 | |||
1961 | next_index = (index & ~(len - 1)) + len; | ||
1962 | last = ((next_index >= hsize) ? 1 : 0); | ||
1963 | error = leaf_dealloc(dip, index, len, leaf_no, bh, | ||
1964 | last); | ||
1965 | brelse(bh); | ||
1966 | if (error) | ||
1967 | goto out; | ||
1968 | index = next_index; | ||
1969 | } else | ||
1970 | index++; | ||
1998 | } | 1971 | } |
1999 | 1972 | ||
2000 | gfs2_trans_end(sdp); | 1973 | if (index != hsize) { |
1974 | gfs2_consist_inode(dip); | ||
1975 | error = -EIO; | ||
1976 | } | ||
1977 | |||
1978 | out: | ||
1979 | kfree(lp); | ||
2001 | 1980 | ||
2002 | return error; | 1981 | return error; |
2003 | } | 1982 | } |
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h index a98f644bd3df..e686af11becd 100644 --- a/fs/gfs2/dir.h +++ b/fs/gfs2/dir.h | |||
@@ -22,8 +22,8 @@ extern struct inode *gfs2_dir_search(struct inode *dir, | |||
22 | extern int gfs2_dir_check(struct inode *dir, const struct qstr *filename, | 22 | extern int gfs2_dir_check(struct inode *dir, const struct qstr *filename, |
23 | const struct gfs2_inode *ip); | 23 | const struct gfs2_inode *ip); |
24 | extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename, | 24 | extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename, |
25 | const struct gfs2_inode *ip, unsigned int type); | 25 | const struct gfs2_inode *ip); |
26 | extern int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); | 26 | extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry); |
27 | extern int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | 27 | extern int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, |
28 | filldir_t filldir); | 28 | filldir_t filldir); |
29 | extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 29 | extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index b5a5e60df0d5..fe9945f2ff72 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c | |||
@@ -139,7 +139,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, | |||
139 | struct gfs2_sbd *sdp = sb->s_fs_info; | 139 | struct gfs2_sbd *sdp = sb->s_fs_info; |
140 | struct inode *inode; | 140 | struct inode *inode; |
141 | 141 | ||
142 | inode = gfs2_ilookup(sb, inum->no_addr); | 142 | inode = gfs2_ilookup(sb, inum->no_addr, 0); |
143 | if (inode) { | 143 | if (inode) { |
144 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { | 144 | if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) { |
145 | iput(inode); | 145 | iput(inode); |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index e48310885c48..a9f5cbe45cd9 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -545,18 +545,10 @@ static int gfs2_close(struct inode *inode, struct file *file) | |||
545 | /** | 545 | /** |
546 | * gfs2_fsync - sync the dirty data for a file (across the cluster) | 546 | * gfs2_fsync - sync the dirty data for a file (across the cluster) |
547 | * @file: the file that points to the dentry (we ignore this) | 547 | * @file: the file that points to the dentry (we ignore this) |
548 | * @dentry: the dentry that points to the inode to sync | 548 | * @datasync: set if we can ignore timestamp changes |
549 | * | 549 | * |
550 | * The VFS will flush "normal" data for us. We only need to worry | 550 | * The VFS will flush data for us. We only need to worry |
551 | * about metadata here. For journaled data, we just do a log flush | 551 | * about metadata here. |
552 | * as we can't avoid it. Otherwise we can just bale out if datasync | ||
553 | * is set. For stuffed inodes we must flush the log in order to | ||
554 | * ensure that all data is on disk. | ||
555 | * | ||
556 | * The call to write_inode_now() is there to write back metadata and | ||
557 | * the inode itself. It does also try and write the data, but thats | ||
558 | * (hopefully) a no-op due to the VFS having already called filemap_fdatawrite() | ||
559 | * for us. | ||
560 | * | 552 | * |
561 | * Returns: errno | 553 | * Returns: errno |
562 | */ | 554 | */ |
@@ -565,22 +557,20 @@ static int gfs2_fsync(struct file *file, int datasync) | |||
565 | { | 557 | { |
566 | struct inode *inode = file->f_mapping->host; | 558 | struct inode *inode = file->f_mapping->host; |
567 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); | 559 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); |
568 | int ret = 0; | 560 | struct gfs2_inode *ip = GFS2_I(inode); |
569 | 561 | int ret; | |
570 | if (gfs2_is_jdata(GFS2_I(inode))) { | ||
571 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
572 | return 0; | ||
573 | } | ||
574 | 562 | ||
575 | if (sync_state != 0) { | 563 | if (datasync) |
576 | if (!datasync) | 564 | sync_state &= ~I_DIRTY_SYNC; |
577 | ret = write_inode_now(inode, 0); | ||
578 | 565 | ||
579 | if (gfs2_is_stuffed(GFS2_I(inode))) | 566 | if (sync_state) { |
580 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | 567 | ret = sync_inode_metadata(inode, 1); |
568 | if (ret) | ||
569 | return ret; | ||
570 | gfs2_ail_flush(ip->i_gl); | ||
581 | } | 571 | } |
582 | 572 | ||
583 | return ret; | 573 | return 0; |
584 | } | 574 | } |
585 | 575 | ||
586 | /** | 576 | /** |
@@ -826,6 +816,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
826 | loff_t bytes, max_bytes; | 816 | loff_t bytes, max_bytes; |
827 | struct gfs2_alloc *al; | 817 | struct gfs2_alloc *al; |
828 | int error; | 818 | int error; |
819 | loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1); | ||
829 | loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; | 820 | loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; |
830 | next = (next + 1) << sdp->sd_sb.sb_bsize_shift; | 821 | next = (next + 1) << sdp->sd_sb.sb_bsize_shift; |
831 | 822 | ||
@@ -833,13 +824,15 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
833 | if (mode & ~FALLOC_FL_KEEP_SIZE) | 824 | if (mode & ~FALLOC_FL_KEEP_SIZE) |
834 | return -EOPNOTSUPP; | 825 | return -EOPNOTSUPP; |
835 | 826 | ||
836 | offset = (offset >> sdp->sd_sb.sb_bsize_shift) << | 827 | offset &= bsize_mask; |
837 | sdp->sd_sb.sb_bsize_shift; | ||
838 | 828 | ||
839 | len = next - offset; | 829 | len = next - offset; |
840 | bytes = sdp->sd_max_rg_data * sdp->sd_sb.sb_bsize / 2; | 830 | bytes = sdp->sd_max_rg_data * sdp->sd_sb.sb_bsize / 2; |
841 | if (!bytes) | 831 | if (!bytes) |
842 | bytes = UINT_MAX; | 832 | bytes = UINT_MAX; |
833 | bytes &= bsize_mask; | ||
834 | if (bytes == 0) | ||
835 | bytes = sdp->sd_sb.sb_bsize; | ||
843 | 836 | ||
844 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); | 837 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); |
845 | error = gfs2_glock_nq(&ip->i_gh); | 838 | error = gfs2_glock_nq(&ip->i_gh); |
@@ -870,6 +863,9 @@ retry: | |||
870 | if (error) { | 863 | if (error) { |
871 | if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) { | 864 | if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) { |
872 | bytes >>= 1; | 865 | bytes >>= 1; |
866 | bytes &= bsize_mask; | ||
867 | if (bytes == 0) | ||
868 | bytes = sdp->sd_sb.sb_bsize; | ||
873 | goto retry; | 869 | goto retry; |
874 | } | 870 | } |
875 | goto out_qunlock; | 871 | goto out_qunlock; |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 7a4fb630a320..a2a6abbccc07 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -143,14 +143,9 @@ static int demote_ok(const struct gfs2_glock *gl) | |||
143 | { | 143 | { |
144 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 144 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
145 | 145 | ||
146 | /* assert_spin_locked(&gl->gl_spin); */ | ||
147 | |||
148 | if (gl->gl_state == LM_ST_UNLOCKED) | 146 | if (gl->gl_state == LM_ST_UNLOCKED) |
149 | return 0; | 147 | return 0; |
150 | if (test_bit(GLF_LFLUSH, &gl->gl_flags)) | 148 | if (!list_empty(&gl->gl_holders)) |
151 | return 0; | ||
152 | if ((gl->gl_name.ln_type != LM_TYPE_INODE) && | ||
153 | !list_empty(&gl->gl_holders)) | ||
154 | return 0; | 149 | return 0; |
155 | if (glops->go_demote_ok) | 150 | if (glops->go_demote_ok) |
156 | return glops->go_demote_ok(gl); | 151 | return glops->go_demote_ok(gl); |
@@ -158,6 +153,31 @@ static int demote_ok(const struct gfs2_glock *gl) | |||
158 | } | 153 | } |
159 | 154 | ||
160 | 155 | ||
156 | void gfs2_glock_add_to_lru(struct gfs2_glock *gl) | ||
157 | { | ||
158 | spin_lock(&lru_lock); | ||
159 | |||
160 | if (!list_empty(&gl->gl_lru)) | ||
161 | list_del_init(&gl->gl_lru); | ||
162 | else | ||
163 | atomic_inc(&lru_count); | ||
164 | |||
165 | list_add_tail(&gl->gl_lru, &lru_list); | ||
166 | set_bit(GLF_LRU, &gl->gl_flags); | ||
167 | spin_unlock(&lru_lock); | ||
168 | } | ||
169 | |||
170 | static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl) | ||
171 | { | ||
172 | spin_lock(&lru_lock); | ||
173 | if (!list_empty(&gl->gl_lru)) { | ||
174 | list_del_init(&gl->gl_lru); | ||
175 | atomic_dec(&lru_count); | ||
176 | clear_bit(GLF_LRU, &gl->gl_flags); | ||
177 | } | ||
178 | spin_unlock(&lru_lock); | ||
179 | } | ||
180 | |||
161 | /** | 181 | /** |
162 | * __gfs2_glock_schedule_for_reclaim - Add a glock to the reclaim list | 182 | * __gfs2_glock_schedule_for_reclaim - Add a glock to the reclaim list |
163 | * @gl: the glock | 183 | * @gl: the glock |
@@ -168,24 +188,8 @@ static int demote_ok(const struct gfs2_glock *gl) | |||
168 | 188 | ||
169 | static void __gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl) | 189 | static void __gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl) |
170 | { | 190 | { |
171 | if (demote_ok(gl)) { | 191 | if (demote_ok(gl)) |
172 | spin_lock(&lru_lock); | 192 | gfs2_glock_add_to_lru(gl); |
173 | |||
174 | if (!list_empty(&gl->gl_lru)) | ||
175 | list_del_init(&gl->gl_lru); | ||
176 | else | ||
177 | atomic_inc(&lru_count); | ||
178 | |||
179 | list_add_tail(&gl->gl_lru, &lru_list); | ||
180 | spin_unlock(&lru_lock); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl) | ||
185 | { | ||
186 | spin_lock(&gl->gl_spin); | ||
187 | __gfs2_glock_schedule_for_reclaim(gl); | ||
188 | spin_unlock(&gl->gl_spin); | ||
189 | } | 193 | } |
190 | 194 | ||
191 | /** | 195 | /** |
@@ -217,12 +221,7 @@ void gfs2_glock_put(struct gfs2_glock *gl) | |||
217 | spin_lock_bucket(gl->gl_hash); | 221 | spin_lock_bucket(gl->gl_hash); |
218 | hlist_bl_del_rcu(&gl->gl_list); | 222 | hlist_bl_del_rcu(&gl->gl_list); |
219 | spin_unlock_bucket(gl->gl_hash); | 223 | spin_unlock_bucket(gl->gl_hash); |
220 | spin_lock(&lru_lock); | 224 | gfs2_glock_remove_from_lru(gl); |
221 | if (!list_empty(&gl->gl_lru)) { | ||
222 | list_del_init(&gl->gl_lru); | ||
223 | atomic_dec(&lru_count); | ||
224 | } | ||
225 | spin_unlock(&lru_lock); | ||
226 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); | 225 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); |
227 | GLOCK_BUG_ON(gl, mapping && mapping->nrpages); | 226 | GLOCK_BUG_ON(gl, mapping && mapping->nrpages); |
228 | trace_gfs2_glock_put(gl); | 227 | trace_gfs2_glock_put(gl); |
@@ -542,11 +541,6 @@ __acquires(&gl->gl_spin) | |||
542 | clear_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); | 541 | clear_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags); |
543 | 542 | ||
544 | gfs2_glock_hold(gl); | 543 | gfs2_glock_hold(gl); |
545 | if (target != LM_ST_UNLOCKED && (gl->gl_state == LM_ST_SHARED || | ||
546 | gl->gl_state == LM_ST_DEFERRED) && | ||
547 | !(lck_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) | ||
548 | lck_flags |= LM_FLAG_TRY_1CB; | ||
549 | |||
550 | if (sdp->sd_lockstruct.ls_ops->lm_lock) { | 544 | if (sdp->sd_lockstruct.ls_ops->lm_lock) { |
551 | /* lock_dlm */ | 545 | /* lock_dlm */ |
552 | ret = sdp->sd_lockstruct.ls_ops->lm_lock(gl, target, lck_flags); | 546 | ret = sdp->sd_lockstruct.ls_ops->lm_lock(gl, target, lck_flags); |
@@ -648,7 +642,7 @@ static void delete_work_func(struct work_struct *work) | |||
648 | /* Note: Unsafe to dereference ip as we don't hold right refs/locks */ | 642 | /* Note: Unsafe to dereference ip as we don't hold right refs/locks */ |
649 | 643 | ||
650 | if (ip) | 644 | if (ip) |
651 | inode = gfs2_ilookup(sdp->sd_vfs, no_addr); | 645 | inode = gfs2_ilookup(sdp->sd_vfs, no_addr, 1); |
652 | else | 646 | else |
653 | inode = gfs2_lookup_by_inum(sdp, no_addr, NULL, GFS2_BLKST_UNLINKED); | 647 | inode = gfs2_lookup_by_inum(sdp, no_addr, NULL, GFS2_BLKST_UNLINKED); |
654 | if (inode && !IS_ERR(inode)) { | 648 | if (inode && !IS_ERR(inode)) { |
@@ -1025,6 +1019,9 @@ int gfs2_glock_nq(struct gfs2_holder *gh) | |||
1025 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | 1019 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) |
1026 | return -EIO; | 1020 | return -EIO; |
1027 | 1021 | ||
1022 | if (test_bit(GLF_LRU, &gl->gl_flags)) | ||
1023 | gfs2_glock_remove_from_lru(gl); | ||
1024 | |||
1028 | spin_lock(&gl->gl_spin); | 1025 | spin_lock(&gl->gl_spin); |
1029 | add_to_queue(gh); | 1026 | add_to_queue(gh); |
1030 | if ((LM_FLAG_NOEXP & gh->gh_flags) && | 1027 | if ((LM_FLAG_NOEXP & gh->gh_flags) && |
@@ -1082,7 +1079,8 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
1082 | !test_bit(GLF_DEMOTE, &gl->gl_flags)) | 1079 | !test_bit(GLF_DEMOTE, &gl->gl_flags)) |
1083 | fast_path = 1; | 1080 | fast_path = 1; |
1084 | } | 1081 | } |
1085 | __gfs2_glock_schedule_for_reclaim(gl); | 1082 | if (!test_bit(GLF_LFLUSH, &gl->gl_flags)) |
1083 | __gfs2_glock_schedule_for_reclaim(gl); | ||
1086 | trace_gfs2_glock_queue(gh, 0); | 1084 | trace_gfs2_glock_queue(gh, 0); |
1087 | spin_unlock(&gl->gl_spin); | 1085 | spin_unlock(&gl->gl_spin); |
1088 | if (likely(fast_path)) | 1086 | if (likely(fast_path)) |
@@ -1365,6 +1363,7 @@ static int gfs2_shrink_glock_memory(struct shrinker *shrink, int nr, gfp_t gfp_m | |||
1365 | while(nr && !list_empty(&lru_list)) { | 1363 | while(nr && !list_empty(&lru_list)) { |
1366 | gl = list_entry(lru_list.next, struct gfs2_glock, gl_lru); | 1364 | gl = list_entry(lru_list.next, struct gfs2_glock, gl_lru); |
1367 | list_del_init(&gl->gl_lru); | 1365 | list_del_init(&gl->gl_lru); |
1366 | clear_bit(GLF_LRU, &gl->gl_flags); | ||
1368 | atomic_dec(&lru_count); | 1367 | atomic_dec(&lru_count); |
1369 | 1368 | ||
1370 | /* Test for being demotable */ | 1369 | /* Test for being demotable */ |
@@ -1387,6 +1386,7 @@ static int gfs2_shrink_glock_memory(struct shrinker *shrink, int nr, gfp_t gfp_m | |||
1387 | } | 1386 | } |
1388 | nr_skipped++; | 1387 | nr_skipped++; |
1389 | list_add(&gl->gl_lru, &skipped); | 1388 | list_add(&gl->gl_lru, &skipped); |
1389 | set_bit(GLF_LRU, &gl->gl_flags); | ||
1390 | } | 1390 | } |
1391 | list_splice(&skipped, &lru_list); | 1391 | list_splice(&skipped, &lru_list); |
1392 | atomic_add(nr_skipped, &lru_count); | 1392 | atomic_add(nr_skipped, &lru_count); |
@@ -1459,12 +1459,7 @@ static void thaw_glock(struct gfs2_glock *gl) | |||
1459 | 1459 | ||
1460 | static void clear_glock(struct gfs2_glock *gl) | 1460 | static void clear_glock(struct gfs2_glock *gl) |
1461 | { | 1461 | { |
1462 | spin_lock(&lru_lock); | 1462 | gfs2_glock_remove_from_lru(gl); |
1463 | if (!list_empty(&gl->gl_lru)) { | ||
1464 | list_del_init(&gl->gl_lru); | ||
1465 | atomic_dec(&lru_count); | ||
1466 | } | ||
1467 | spin_unlock(&lru_lock); | ||
1468 | 1463 | ||
1469 | spin_lock(&gl->gl_spin); | 1464 | spin_lock(&gl->gl_spin); |
1470 | if (gl->gl_state != LM_ST_UNLOCKED) | 1465 | if (gl->gl_state != LM_ST_UNLOCKED) |
@@ -1599,9 +1594,11 @@ static int dump_holder(struct seq_file *seq, const struct gfs2_holder *gh) | |||
1599 | return 0; | 1594 | return 0; |
1600 | } | 1595 | } |
1601 | 1596 | ||
1602 | static const char *gflags2str(char *buf, const unsigned long *gflags) | 1597 | static const char *gflags2str(char *buf, const struct gfs2_glock *gl) |
1603 | { | 1598 | { |
1599 | const unsigned long *gflags = &gl->gl_flags; | ||
1604 | char *p = buf; | 1600 | char *p = buf; |
1601 | |||
1605 | if (test_bit(GLF_LOCK, gflags)) | 1602 | if (test_bit(GLF_LOCK, gflags)) |
1606 | *p++ = 'l'; | 1603 | *p++ = 'l'; |
1607 | if (test_bit(GLF_DEMOTE, gflags)) | 1604 | if (test_bit(GLF_DEMOTE, gflags)) |
@@ -1624,6 +1621,10 @@ static const char *gflags2str(char *buf, const unsigned long *gflags) | |||
1624 | *p++ = 'F'; | 1621 | *p++ = 'F'; |
1625 | if (test_bit(GLF_QUEUED, gflags)) | 1622 | if (test_bit(GLF_QUEUED, gflags)) |
1626 | *p++ = 'q'; | 1623 | *p++ = 'q'; |
1624 | if (test_bit(GLF_LRU, gflags)) | ||
1625 | *p++ = 'L'; | ||
1626 | if (gl->gl_object) | ||
1627 | *p++ = 'o'; | ||
1627 | *p = 0; | 1628 | *p = 0; |
1628 | return buf; | 1629 | return buf; |
1629 | } | 1630 | } |
@@ -1658,14 +1659,15 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl) | |||
1658 | dtime *= 1000000/HZ; /* demote time in uSec */ | 1659 | dtime *= 1000000/HZ; /* demote time in uSec */ |
1659 | if (!test_bit(GLF_DEMOTE, &gl->gl_flags)) | 1660 | if (!test_bit(GLF_DEMOTE, &gl->gl_flags)) |
1660 | dtime = 0; | 1661 | dtime = 0; |
1661 | gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d r:%d\n", | 1662 | gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d v:%d r:%d\n", |
1662 | state2str(gl->gl_state), | 1663 | state2str(gl->gl_state), |
1663 | gl->gl_name.ln_type, | 1664 | gl->gl_name.ln_type, |
1664 | (unsigned long long)gl->gl_name.ln_number, | 1665 | (unsigned long long)gl->gl_name.ln_number, |
1665 | gflags2str(gflags_buf, &gl->gl_flags), | 1666 | gflags2str(gflags_buf, gl), |
1666 | state2str(gl->gl_target), | 1667 | state2str(gl->gl_target), |
1667 | state2str(gl->gl_demote_state), dtime, | 1668 | state2str(gl->gl_demote_state), dtime, |
1668 | atomic_read(&gl->gl_ail_count), | 1669 | atomic_read(&gl->gl_ail_count), |
1670 | atomic_read(&gl->gl_revokes), | ||
1669 | atomic_read(&gl->gl_ref)); | 1671 | atomic_read(&gl->gl_ref)); |
1670 | 1672 | ||
1671 | list_for_each_entry(gh, &gl->gl_holders, gh_list) { | 1673 | list_for_each_entry(gh, &gl->gl_holders, gh_list) { |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index aea160690e94..6b2f757b9281 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -225,11 +225,10 @@ static inline int gfs2_glock_nq_init(struct gfs2_glock *gl, | |||
225 | 225 | ||
226 | extern void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state); | 226 | extern void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state); |
227 | extern void gfs2_glock_complete(struct gfs2_glock *gl, int ret); | 227 | extern void gfs2_glock_complete(struct gfs2_glock *gl, int ret); |
228 | extern void gfs2_reclaim_glock(struct gfs2_sbd *sdp); | ||
229 | extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp); | 228 | extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp); |
230 | extern void gfs2_glock_finish_truncate(struct gfs2_inode *ip); | 229 | extern void gfs2_glock_finish_truncate(struct gfs2_inode *ip); |
231 | extern void gfs2_glock_thaw(struct gfs2_sbd *sdp); | 230 | extern void gfs2_glock_thaw(struct gfs2_sbd *sdp); |
232 | extern void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl); | 231 | extern void gfs2_glock_add_to_lru(struct gfs2_glock *gl); |
233 | extern void gfs2_glock_free(struct gfs2_glock *gl); | 232 | extern void gfs2_glock_free(struct gfs2_glock *gl); |
234 | 233 | ||
235 | extern int __init gfs2_glock_init(void); | 234 | extern int __init gfs2_glock_init(void); |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 25eeb2bcee47..8ef70f464731 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -28,33 +28,18 @@ | |||
28 | #include "trans.h" | 28 | #include "trans.h" |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * ail_empty_gl - remove all buffers for a given lock from the AIL | 31 | * __gfs2_ail_flush - remove all buffers for a given lock from the AIL |
32 | * @gl: the glock | 32 | * @gl: the glock |
33 | * | 33 | * |
34 | * None of the buffers should be dirty, locked, or pinned. | 34 | * None of the buffers should be dirty, locked, or pinned. |
35 | */ | 35 | */ |
36 | 36 | ||
37 | static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | 37 | static void __gfs2_ail_flush(struct gfs2_glock *gl) |
38 | { | 38 | { |
39 | struct gfs2_sbd *sdp = gl->gl_sbd; | 39 | struct gfs2_sbd *sdp = gl->gl_sbd; |
40 | struct list_head *head = &gl->gl_ail_list; | 40 | struct list_head *head = &gl->gl_ail_list; |
41 | struct gfs2_bufdata *bd; | 41 | struct gfs2_bufdata *bd; |
42 | struct buffer_head *bh; | 42 | struct buffer_head *bh; |
43 | struct gfs2_trans tr; | ||
44 | |||
45 | memset(&tr, 0, sizeof(tr)); | ||
46 | tr.tr_revokes = atomic_read(&gl->gl_ail_count); | ||
47 | |||
48 | if (!tr.tr_revokes) | ||
49 | return; | ||
50 | |||
51 | /* A shortened, inline version of gfs2_trans_begin() */ | ||
52 | tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); | ||
53 | tr.tr_ip = (unsigned long)__builtin_return_address(0); | ||
54 | INIT_LIST_HEAD(&tr.tr_list_buf); | ||
55 | gfs2_log_reserve(sdp, tr.tr_reserved); | ||
56 | BUG_ON(current->journal_info); | ||
57 | current->journal_info = &tr; | ||
58 | 43 | ||
59 | spin_lock(&sdp->sd_ail_lock); | 44 | spin_lock(&sdp->sd_ail_lock); |
60 | while (!list_empty(head)) { | 45 | while (!list_empty(head)) { |
@@ -76,7 +61,47 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
76 | } | 61 | } |
77 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); | 62 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); |
78 | spin_unlock(&sdp->sd_ail_lock); | 63 | spin_unlock(&sdp->sd_ail_lock); |
64 | } | ||
65 | |||
66 | |||
67 | static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | ||
68 | { | ||
69 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
70 | struct gfs2_trans tr; | ||
71 | |||
72 | memset(&tr, 0, sizeof(tr)); | ||
73 | tr.tr_revokes = atomic_read(&gl->gl_ail_count); | ||
74 | |||
75 | if (!tr.tr_revokes) | ||
76 | return; | ||
77 | |||
78 | /* A shortened, inline version of gfs2_trans_begin() */ | ||
79 | tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); | ||
80 | tr.tr_ip = (unsigned long)__builtin_return_address(0); | ||
81 | INIT_LIST_HEAD(&tr.tr_list_buf); | ||
82 | gfs2_log_reserve(sdp, tr.tr_reserved); | ||
83 | BUG_ON(current->journal_info); | ||
84 | current->journal_info = &tr; | ||
85 | |||
86 | __gfs2_ail_flush(gl); | ||
87 | |||
88 | gfs2_trans_end(sdp); | ||
89 | gfs2_log_flush(sdp, NULL); | ||
90 | } | ||
91 | |||
92 | void gfs2_ail_flush(struct gfs2_glock *gl) | ||
93 | { | ||
94 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
95 | unsigned int revokes = atomic_read(&gl->gl_ail_count); | ||
96 | int ret; | ||
97 | |||
98 | if (!revokes) | ||
99 | return; | ||
79 | 100 | ||
101 | ret = gfs2_trans_begin(sdp, 0, revokes); | ||
102 | if (ret) | ||
103 | return; | ||
104 | __gfs2_ail_flush(gl); | ||
80 | gfs2_trans_end(sdp); | 105 | gfs2_trans_end(sdp); |
81 | gfs2_log_flush(sdp, NULL); | 106 | gfs2_log_flush(sdp, NULL); |
82 | } | 107 | } |
@@ -227,6 +252,119 @@ static int inode_go_demote_ok(const struct gfs2_glock *gl) | |||
227 | } | 252 | } |
228 | 253 | ||
229 | /** | 254 | /** |
255 | * gfs2_set_nlink - Set the inode's link count based on on-disk info | ||
256 | * @inode: The inode in question | ||
257 | * @nlink: The link count | ||
258 | * | ||
259 | * If the link count has hit zero, it must never be raised, whatever the | ||
260 | * on-disk inode might say. When new struct inodes are created the link | ||
261 | * count is set to 1, so that we can safely use this test even when reading | ||
262 | * in on disk information for the first time. | ||
263 | */ | ||
264 | |||
265 | static void gfs2_set_nlink(struct inode *inode, u32 nlink) | ||
266 | { | ||
267 | /* | ||
268 | * We will need to review setting the nlink count here in the | ||
269 | * light of the forthcoming ro bind mount work. This is a reminder | ||
270 | * to do that. | ||
271 | */ | ||
272 | if ((inode->i_nlink != nlink) && (inode->i_nlink != 0)) { | ||
273 | if (nlink == 0) | ||
274 | clear_nlink(inode); | ||
275 | else | ||
276 | inode->i_nlink = nlink; | ||
277 | } | ||
278 | } | ||
279 | |||
280 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | ||
281 | { | ||
282 | const struct gfs2_dinode *str = buf; | ||
283 | struct timespec atime; | ||
284 | u16 height, depth; | ||
285 | |||
286 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) | ||
287 | goto corrupt; | ||
288 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); | ||
289 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | ||
290 | ip->i_inode.i_rdev = 0; | ||
291 | switch (ip->i_inode.i_mode & S_IFMT) { | ||
292 | case S_IFBLK: | ||
293 | case S_IFCHR: | ||
294 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), | ||
295 | be32_to_cpu(str->di_minor)); | ||
296 | break; | ||
297 | }; | ||
298 | |||
299 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); | ||
300 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); | ||
301 | gfs2_set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink)); | ||
302 | i_size_write(&ip->i_inode, be64_to_cpu(str->di_size)); | ||
303 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); | ||
304 | atime.tv_sec = be64_to_cpu(str->di_atime); | ||
305 | atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); | ||
306 | if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0) | ||
307 | ip->i_inode.i_atime = atime; | ||
308 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | ||
309 | ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); | ||
310 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | ||
311 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); | ||
312 | |||
313 | ip->i_goal = be64_to_cpu(str->di_goal_meta); | ||
314 | ip->i_generation = be64_to_cpu(str->di_generation); | ||
315 | |||
316 | ip->i_diskflags = be32_to_cpu(str->di_flags); | ||
317 | gfs2_set_inode_flags(&ip->i_inode); | ||
318 | height = be16_to_cpu(str->di_height); | ||
319 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) | ||
320 | goto corrupt; | ||
321 | ip->i_height = (u8)height; | ||
322 | |||
323 | depth = be16_to_cpu(str->di_depth); | ||
324 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) | ||
325 | goto corrupt; | ||
326 | ip->i_depth = (u8)depth; | ||
327 | ip->i_entries = be32_to_cpu(str->di_entries); | ||
328 | |||
329 | ip->i_eattr = be64_to_cpu(str->di_eattr); | ||
330 | if (S_ISREG(ip->i_inode.i_mode)) | ||
331 | gfs2_set_aops(&ip->i_inode); | ||
332 | |||
333 | return 0; | ||
334 | corrupt: | ||
335 | gfs2_consist_inode(ip); | ||
336 | return -EIO; | ||
337 | } | ||
338 | |||
339 | /** | ||
340 | * gfs2_inode_refresh - Refresh the incore copy of the dinode | ||
341 | * @ip: The GFS2 inode | ||
342 | * | ||
343 | * Returns: errno | ||
344 | */ | ||
345 | |||
346 | int gfs2_inode_refresh(struct gfs2_inode *ip) | ||
347 | { | ||
348 | struct buffer_head *dibh; | ||
349 | int error; | ||
350 | |||
351 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
352 | if (error) | ||
353 | return error; | ||
354 | |||
355 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) { | ||
356 | brelse(dibh); | ||
357 | return -EIO; | ||
358 | } | ||
359 | |||
360 | error = gfs2_dinode_in(ip, dibh->b_data); | ||
361 | brelse(dibh); | ||
362 | clear_bit(GIF_INVALID, &ip->i_flags); | ||
363 | |||
364 | return error; | ||
365 | } | ||
366 | |||
367 | /** | ||
230 | * inode_go_lock - operation done after an inode lock is locked by a process | 368 | * inode_go_lock - operation done after an inode lock is locked by a process |
231 | * @gl: the glock | 369 | * @gl: the glock |
232 | * @flags: | 370 | * @flags: |
diff --git a/fs/gfs2/glops.h b/fs/gfs2/glops.h index b3aa2e3210fd..6fce409b5a50 100644 --- a/fs/gfs2/glops.h +++ b/fs/gfs2/glops.h | |||
@@ -23,4 +23,6 @@ extern const struct gfs2_glock_operations gfs2_quota_glops; | |||
23 | extern const struct gfs2_glock_operations gfs2_journal_glops; | 23 | extern const struct gfs2_glock_operations gfs2_journal_glops; |
24 | extern const struct gfs2_glock_operations *gfs2_glops_list[]; | 24 | extern const struct gfs2_glock_operations *gfs2_glops_list[]; |
25 | 25 | ||
26 | extern void gfs2_ail_flush(struct gfs2_glock *gl); | ||
27 | |||
26 | #endif /* __GLOPS_DOT_H__ */ | 28 | #endif /* __GLOPS_DOT_H__ */ |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 870a89d6d4dc..0a064e91ac70 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #define DIO_WAIT 0x00000010 | 21 | #define DIO_WAIT 0x00000010 |
22 | #define DIO_METADATA 0x00000020 | 22 | #define DIO_METADATA 0x00000020 |
23 | #define DIO_ALL 0x00000100 | ||
24 | 23 | ||
25 | struct gfs2_log_operations; | 24 | struct gfs2_log_operations; |
26 | struct gfs2_log_element; | 25 | struct gfs2_log_element; |
@@ -200,6 +199,8 @@ enum { | |||
200 | GLF_INITIAL = 10, | 199 | GLF_INITIAL = 10, |
201 | GLF_FROZEN = 11, | 200 | GLF_FROZEN = 11, |
202 | GLF_QUEUED = 12, | 201 | GLF_QUEUED = 12, |
202 | GLF_LRU = 13, | ||
203 | GLF_OBJECT = 14, /* Used only for tracing */ | ||
203 | }; | 204 | }; |
204 | 205 | ||
205 | struct gfs2_glock { | 206 | struct gfs2_glock { |
@@ -234,6 +235,7 @@ struct gfs2_glock { | |||
234 | 235 | ||
235 | struct list_head gl_ail_list; | 236 | struct list_head gl_ail_list; |
236 | atomic_t gl_ail_count; | 237 | atomic_t gl_ail_count; |
238 | atomic_t gl_revokes; | ||
237 | struct delayed_work gl_work; | 239 | struct delayed_work gl_work; |
238 | struct work_struct gl_delete; | 240 | struct work_struct gl_delete; |
239 | struct rcu_head gl_rcu; | 241 | struct rcu_head gl_rcu; |
@@ -374,8 +376,6 @@ struct gfs2_ail { | |||
374 | unsigned int ai_first; | 376 | unsigned int ai_first; |
375 | struct list_head ai_ail1_list; | 377 | struct list_head ai_ail1_list; |
376 | struct list_head ai_ail2_list; | 378 | struct list_head ai_ail2_list; |
377 | |||
378 | u64 ai_sync_gen; | ||
379 | }; | 379 | }; |
380 | 380 | ||
381 | struct gfs2_journal_extent { | 381 | struct gfs2_journal_extent { |
@@ -488,7 +488,6 @@ struct gfs2_sb_host { | |||
488 | 488 | ||
489 | char sb_lockproto[GFS2_LOCKNAME_LEN]; | 489 | char sb_lockproto[GFS2_LOCKNAME_LEN]; |
490 | char sb_locktable[GFS2_LOCKNAME_LEN]; | 490 | char sb_locktable[GFS2_LOCKNAME_LEN]; |
491 | u8 sb_uuid[16]; | ||
492 | }; | 491 | }; |
493 | 492 | ||
494 | /* | 493 | /* |
@@ -654,7 +653,6 @@ struct gfs2_sbd { | |||
654 | spinlock_t sd_ail_lock; | 653 | spinlock_t sd_ail_lock; |
655 | struct list_head sd_ail1_list; | 654 | struct list_head sd_ail1_list; |
656 | struct list_head sd_ail2_list; | 655 | struct list_head sd_ail2_list; |
657 | u64 sd_ail_sync_gen; | ||
658 | 656 | ||
659 | /* Replay stuff */ | 657 | /* Replay stuff */ |
660 | 658 | ||
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 9134dcb89479..03e0c529063e 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -1,23 +1,25 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/sched.h> | ||
11 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
12 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
13 | #include <linux/completion.h> | 12 | #include <linux/completion.h> |
14 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/namei.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/xattr.h> | ||
15 | #include <linux/posix_acl.h> | 17 | #include <linux/posix_acl.h> |
16 | #include <linux/sort.h> | ||
17 | #include <linux/gfs2_ondisk.h> | 18 | #include <linux/gfs2_ondisk.h> |
18 | #include <linux/crc32.h> | 19 | #include <linux/crc32.h> |
20 | #include <linux/fiemap.h> | ||
19 | #include <linux/security.h> | 21 | #include <linux/security.h> |
20 | #include <linux/time.h> | 22 | #include <asm/uaccess.h> |
21 | 23 | ||
22 | #include "gfs2.h" | 24 | #include "gfs2.h" |
23 | #include "incore.h" | 25 | #include "incore.h" |
@@ -26,19 +28,14 @@ | |||
26 | #include "dir.h" | 28 | #include "dir.h" |
27 | #include "xattr.h" | 29 | #include "xattr.h" |
28 | #include "glock.h" | 30 | #include "glock.h" |
29 | #include "glops.h" | ||
30 | #include "inode.h" | 31 | #include "inode.h" |
31 | #include "log.h" | ||
32 | #include "meta_io.h" | 32 | #include "meta_io.h" |
33 | #include "quota.h" | 33 | #include "quota.h" |
34 | #include "rgrp.h" | 34 | #include "rgrp.h" |
35 | #include "trans.h" | 35 | #include "trans.h" |
36 | #include "util.h" | 36 | #include "util.h" |
37 | 37 | #include "super.h" | |
38 | struct gfs2_inum_range_host { | 38 | #include "glops.h" |
39 | u64 ir_start; | ||
40 | u64 ir_length; | ||
41 | }; | ||
42 | 39 | ||
43 | struct gfs2_skip_data { | 40 | struct gfs2_skip_data { |
44 | u64 no_addr; | 41 | u64 no_addr; |
@@ -74,14 +71,14 @@ static int iget_set(struct inode *inode, void *opaque) | |||
74 | return 0; | 71 | return 0; |
75 | } | 72 | } |
76 | 73 | ||
77 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) | 74 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr, int non_block) |
78 | { | 75 | { |
79 | unsigned long hash = (unsigned long)no_addr; | 76 | unsigned long hash = (unsigned long)no_addr; |
80 | struct gfs2_skip_data data; | 77 | struct gfs2_skip_data data; |
81 | 78 | ||
82 | data.no_addr = no_addr; | 79 | data.no_addr = no_addr; |
83 | data.skipped = 0; | 80 | data.skipped = 0; |
84 | data.non_block = 0; | 81 | data.non_block = non_block; |
85 | return ilookup5(sb, hash, iget_test, &data); | 82 | return ilookup5(sb, hash, iget_test, &data); |
86 | } | 83 | } |
87 | 84 | ||
@@ -248,203 +245,6 @@ fail_iput: | |||
248 | goto fail; | 245 | goto fail; |
249 | } | 246 | } |
250 | 247 | ||
251 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | ||
252 | { | ||
253 | const struct gfs2_dinode *str = buf; | ||
254 | struct timespec atime; | ||
255 | u16 height, depth; | ||
256 | |||
257 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) | ||
258 | goto corrupt; | ||
259 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); | ||
260 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | ||
261 | ip->i_inode.i_rdev = 0; | ||
262 | switch (ip->i_inode.i_mode & S_IFMT) { | ||
263 | case S_IFBLK: | ||
264 | case S_IFCHR: | ||
265 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), | ||
266 | be32_to_cpu(str->di_minor)); | ||
267 | break; | ||
268 | }; | ||
269 | |||
270 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); | ||
271 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); | ||
272 | /* | ||
273 | * We will need to review setting the nlink count here in the | ||
274 | * light of the forthcoming ro bind mount work. This is a reminder | ||
275 | * to do that. | ||
276 | */ | ||
277 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); | ||
278 | i_size_write(&ip->i_inode, be64_to_cpu(str->di_size)); | ||
279 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); | ||
280 | atime.tv_sec = be64_to_cpu(str->di_atime); | ||
281 | atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); | ||
282 | if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0) | ||
283 | ip->i_inode.i_atime = atime; | ||
284 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | ||
285 | ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec); | ||
286 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | ||
287 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); | ||
288 | |||
289 | ip->i_goal = be64_to_cpu(str->di_goal_meta); | ||
290 | ip->i_generation = be64_to_cpu(str->di_generation); | ||
291 | |||
292 | ip->i_diskflags = be32_to_cpu(str->di_flags); | ||
293 | gfs2_set_inode_flags(&ip->i_inode); | ||
294 | height = be16_to_cpu(str->di_height); | ||
295 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) | ||
296 | goto corrupt; | ||
297 | ip->i_height = (u8)height; | ||
298 | |||
299 | depth = be16_to_cpu(str->di_depth); | ||
300 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) | ||
301 | goto corrupt; | ||
302 | ip->i_depth = (u8)depth; | ||
303 | ip->i_entries = be32_to_cpu(str->di_entries); | ||
304 | |||
305 | ip->i_eattr = be64_to_cpu(str->di_eattr); | ||
306 | if (S_ISREG(ip->i_inode.i_mode)) | ||
307 | gfs2_set_aops(&ip->i_inode); | ||
308 | |||
309 | return 0; | ||
310 | corrupt: | ||
311 | if (gfs2_consist_inode(ip)) | ||
312 | gfs2_dinode_print(ip); | ||
313 | return -EIO; | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * gfs2_inode_refresh - Refresh the incore copy of the dinode | ||
318 | * @ip: The GFS2 inode | ||
319 | * | ||
320 | * Returns: errno | ||
321 | */ | ||
322 | |||
323 | int gfs2_inode_refresh(struct gfs2_inode *ip) | ||
324 | { | ||
325 | struct buffer_head *dibh; | ||
326 | int error; | ||
327 | |||
328 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
329 | if (error) | ||
330 | return error; | ||
331 | |||
332 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) { | ||
333 | brelse(dibh); | ||
334 | return -EIO; | ||
335 | } | ||
336 | |||
337 | error = gfs2_dinode_in(ip, dibh->b_data); | ||
338 | brelse(dibh); | ||
339 | clear_bit(GIF_INVALID, &ip->i_flags); | ||
340 | |||
341 | return error; | ||
342 | } | ||
343 | |||
344 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) | ||
345 | { | ||
346 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
347 | struct gfs2_alloc *al; | ||
348 | struct gfs2_rgrpd *rgd; | ||
349 | int error; | ||
350 | |||
351 | if (gfs2_get_inode_blocks(&ip->i_inode) != 1) { | ||
352 | if (gfs2_consist_inode(ip)) | ||
353 | gfs2_dinode_print(ip); | ||
354 | return -EIO; | ||
355 | } | ||
356 | |||
357 | al = gfs2_alloc_get(ip); | ||
358 | if (!al) | ||
359 | return -ENOMEM; | ||
360 | |||
361 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | ||
362 | if (error) | ||
363 | goto out; | ||
364 | |||
365 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | ||
366 | if (error) | ||
367 | goto out_qs; | ||
368 | |||
369 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | ||
370 | if (!rgd) { | ||
371 | gfs2_consist_inode(ip); | ||
372 | error = -EIO; | ||
373 | goto out_rindex_relse; | ||
374 | } | ||
375 | |||
376 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, | ||
377 | &al->al_rgd_gh); | ||
378 | if (error) | ||
379 | goto out_rindex_relse; | ||
380 | |||
381 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, 1); | ||
382 | if (error) | ||
383 | goto out_rg_gunlock; | ||
384 | |||
385 | set_bit(GLF_DIRTY, &ip->i_gl->gl_flags); | ||
386 | set_bit(GLF_LFLUSH, &ip->i_gl->gl_flags); | ||
387 | |||
388 | gfs2_free_di(rgd, ip); | ||
389 | |||
390 | gfs2_trans_end(sdp); | ||
391 | |||
392 | out_rg_gunlock: | ||
393 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | ||
394 | out_rindex_relse: | ||
395 | gfs2_glock_dq_uninit(&al->al_ri_gh); | ||
396 | out_qs: | ||
397 | gfs2_quota_unhold(ip); | ||
398 | out: | ||
399 | gfs2_alloc_put(ip); | ||
400 | return error; | ||
401 | } | ||
402 | |||
403 | /** | ||
404 | * gfs2_change_nlink - Change nlink count on inode | ||
405 | * @ip: The GFS2 inode | ||
406 | * @diff: The change in the nlink count required | ||
407 | * | ||
408 | * Returns: errno | ||
409 | */ | ||
410 | int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | ||
411 | { | ||
412 | struct buffer_head *dibh; | ||
413 | u32 nlink; | ||
414 | int error; | ||
415 | |||
416 | BUG_ON(diff != 1 && diff != -1); | ||
417 | nlink = ip->i_inode.i_nlink + diff; | ||
418 | |||
419 | /* If we are reducing the nlink count, but the new value ends up being | ||
420 | bigger than the old one, we must have underflowed. */ | ||
421 | if (diff < 0 && nlink > ip->i_inode.i_nlink) { | ||
422 | if (gfs2_consist_inode(ip)) | ||
423 | gfs2_dinode_print(ip); | ||
424 | return -EIO; | ||
425 | } | ||
426 | |||
427 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
428 | if (error) | ||
429 | return error; | ||
430 | |||
431 | if (diff > 0) | ||
432 | inc_nlink(&ip->i_inode); | ||
433 | else | ||
434 | drop_nlink(&ip->i_inode); | ||
435 | |||
436 | ip->i_inode.i_ctime = CURRENT_TIME; | ||
437 | |||
438 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
439 | gfs2_dinode_out(ip, dibh->b_data); | ||
440 | brelse(dibh); | ||
441 | mark_inode_dirty(&ip->i_inode); | ||
442 | |||
443 | if (ip->i_inode.i_nlink == 0) | ||
444 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ | ||
445 | |||
446 | return error; | ||
447 | } | ||
448 | 248 | ||
449 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) | 249 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) |
450 | { | 250 | { |
@@ -543,7 +343,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
543 | 343 | ||
544 | /* Don't create entries in an unlinked directory */ | 344 | /* Don't create entries in an unlinked directory */ |
545 | if (!dip->i_inode.i_nlink) | 345 | if (!dip->i_inode.i_nlink) |
546 | return -EPERM; | 346 | return -ENOENT; |
547 | 347 | ||
548 | error = gfs2_dir_check(&dip->i_inode, name, NULL); | 348 | error = gfs2_dir_check(&dip->i_inode, name, NULL); |
549 | switch (error) { | 349 | switch (error) { |
@@ -613,21 +413,44 @@ out: | |||
613 | return error; | 413 | return error; |
614 | } | 414 | } |
615 | 415 | ||
416 | static void gfs2_init_dir(struct buffer_head *dibh, | ||
417 | const struct gfs2_inode *parent) | ||
418 | { | ||
419 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; | ||
420 | struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); | ||
421 | |||
422 | gfs2_qstr2dirent(&gfs2_qdot, GFS2_DIRENT_SIZE(gfs2_qdot.len), dent); | ||
423 | dent->de_inum = di->di_num; /* already GFS2 endian */ | ||
424 | dent->de_type = cpu_to_be16(DT_DIR); | ||
425 | |||
426 | dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); | ||
427 | gfs2_qstr2dirent(&gfs2_qdotdot, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); | ||
428 | gfs2_inum_out(parent, dent); | ||
429 | dent->de_type = cpu_to_be16(DT_DIR); | ||
430 | |||
431 | } | ||
432 | |||
616 | /** | 433 | /** |
617 | * init_dinode - Fill in a new dinode structure | 434 | * init_dinode - Fill in a new dinode structure |
618 | * @dip: the directory this inode is being created in | 435 | * @dip: The directory this inode is being created in |
619 | * @gl: The glock covering the new inode | 436 | * @gl: The glock covering the new inode |
620 | * @inum: the inode number | 437 | * @inum: The inode number |
621 | * @mode: the file permissions | 438 | * @mode: The file permissions |
622 | * @uid: | 439 | * @uid: The uid of the new inode |
623 | * @gid: | 440 | * @gid: The gid of the new inode |
441 | * @generation: The generation number of the new inode | ||
442 | * @dev: The device number (if a device node) | ||
443 | * @symname: The symlink destination (if a symlink) | ||
444 | * @size: The inode size (ignored for directories) | ||
445 | * @bhp: The buffer head (returned to caller) | ||
624 | * | 446 | * |
625 | */ | 447 | */ |
626 | 448 | ||
627 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 449 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
628 | const struct gfs2_inum_host *inum, unsigned int mode, | 450 | const struct gfs2_inum_host *inum, unsigned int mode, |
629 | unsigned int uid, unsigned int gid, | 451 | unsigned int uid, unsigned int gid, |
630 | const u64 *generation, dev_t dev, struct buffer_head **bhp) | 452 | const u64 *generation, dev_t dev, const char *symname, |
453 | unsigned size, struct buffer_head **bhp) | ||
631 | { | 454 | { |
632 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 455 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
633 | struct gfs2_dinode *di; | 456 | struct gfs2_dinode *di; |
@@ -646,7 +469,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
646 | di->di_uid = cpu_to_be32(uid); | 469 | di->di_uid = cpu_to_be32(uid); |
647 | di->di_gid = cpu_to_be32(gid); | 470 | di->di_gid = cpu_to_be32(gid); |
648 | di->di_nlink = 0; | 471 | di->di_nlink = 0; |
649 | di->di_size = 0; | 472 | di->di_size = cpu_to_be64(size); |
650 | di->di_blocks = cpu_to_be64(1); | 473 | di->di_blocks = cpu_to_be64(1); |
651 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); | 474 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); |
652 | di->di_major = cpu_to_be32(MAJOR(dev)); | 475 | di->di_major = cpu_to_be32(MAJOR(dev)); |
@@ -654,16 +477,6 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
654 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 477 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); |
655 | di->di_generation = cpu_to_be64(*generation); | 478 | di->di_generation = cpu_to_be64(*generation); |
656 | di->di_flags = 0; | 479 | di->di_flags = 0; |
657 | |||
658 | if (S_ISREG(mode)) { | ||
659 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | ||
660 | gfs2_tune_get(sdp, gt_new_files_jdata)) | ||
661 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | ||
662 | } else if (S_ISDIR(mode)) { | ||
663 | di->di_flags |= cpu_to_be32(dip->i_diskflags & | ||
664 | GFS2_DIF_INHERIT_JDATA); | ||
665 | } | ||
666 | |||
667 | di->__pad1 = 0; | 480 | di->__pad1 = 0; |
668 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); | 481 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); |
669 | di->di_height = 0; | 482 | di->di_height = 0; |
@@ -677,7 +490,26 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
677 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); | 490 | di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); |
678 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); | 491 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); |
679 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 492 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
680 | 493 | ||
494 | switch(mode & S_IFMT) { | ||
495 | case S_IFREG: | ||
496 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | ||
497 | gfs2_tune_get(sdp, gt_new_files_jdata)) | ||
498 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | ||
499 | break; | ||
500 | case S_IFDIR: | ||
501 | di->di_flags |= cpu_to_be32(dip->i_diskflags & | ||
502 | GFS2_DIF_INHERIT_JDATA); | ||
503 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | ||
504 | di->di_size = cpu_to_be64(sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)); | ||
505 | di->di_entries = cpu_to_be32(2); | ||
506 | gfs2_init_dir(dibh, dip); | ||
507 | break; | ||
508 | case S_IFLNK: | ||
509 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, size); | ||
510 | break; | ||
511 | } | ||
512 | |||
681 | set_buffer_uptodate(dibh); | 513 | set_buffer_uptodate(dibh); |
682 | 514 | ||
683 | *bhp = dibh; | 515 | *bhp = dibh; |
@@ -685,7 +517,8 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
685 | 517 | ||
686 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 518 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
687 | unsigned int mode, const struct gfs2_inum_host *inum, | 519 | unsigned int mode, const struct gfs2_inum_host *inum, |
688 | const u64 *generation, dev_t dev, struct buffer_head **bhp) | 520 | const u64 *generation, dev_t dev, const char *symname, |
521 | unsigned int size, struct buffer_head **bhp) | ||
689 | { | 522 | { |
690 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 523 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
691 | unsigned int uid, gid; | 524 | unsigned int uid, gid; |
@@ -707,7 +540,7 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
707 | if (error) | 540 | if (error) |
708 | goto out_quota; | 541 | goto out_quota; |
709 | 542 | ||
710 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, bhp); | 543 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, symname, size, bhp); |
711 | gfs2_quota_change(dip, +1, uid, gid); | 544 | gfs2_quota_change(dip, +1, uid, gid); |
712 | gfs2_trans_end(sdp); | 545 | gfs2_trans_end(sdp); |
713 | 546 | ||
@@ -761,14 +594,16 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
761 | goto fail_quota_locks; | 594 | goto fail_quota_locks; |
762 | } | 595 | } |
763 | 596 | ||
764 | error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); | 597 | error = gfs2_dir_add(&dip->i_inode, name, ip); |
765 | if (error) | 598 | if (error) |
766 | goto fail_end_trans; | 599 | goto fail_end_trans; |
767 | 600 | ||
768 | error = gfs2_meta_inode_buffer(ip, &dibh); | 601 | error = gfs2_meta_inode_buffer(ip, &dibh); |
769 | if (error) | 602 | if (error) |
770 | goto fail_end_trans; | 603 | goto fail_end_trans; |
771 | ip->i_inode.i_nlink = 1; | 604 | inc_nlink(&ip->i_inode); |
605 | if (S_ISDIR(ip->i_inode.i_mode)) | ||
606 | inc_nlink(&ip->i_inode); | ||
772 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 607 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
773 | gfs2_dinode_out(ip, dibh->b_data); | 608 | gfs2_dinode_out(ip, dibh->b_data); |
774 | brelse(dibh); | 609 | brelse(dibh); |
@@ -815,27 +650,25 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip, | |||
815 | } | 650 | } |
816 | 651 | ||
817 | /** | 652 | /** |
818 | * gfs2_createi - Create a new inode | 653 | * gfs2_create_inode - Create a new inode |
819 | * @ghs: An array of two holders | 654 | * @dir: The parent directory |
820 | * @name: The name of the new file | 655 | * @dentry: The new dentry |
821 | * @mode: the permissions on the new inode | 656 | * @mode: The permissions on the new inode |
822 | * | 657 | * @dev: For device nodes, this is the device number |
823 | * @ghs[0] is an initialized holder for the directory | 658 | * @symname: For symlinks, this is the link destination |
824 | * @ghs[1] is the holder for the inode lock | 659 | * @size: The initial size of the inode (ignored for directories) |
825 | * | 660 | * |
826 | * If the return value is not NULL, the glocks on both the directory and the new | 661 | * Returns: 0 on success, or error code |
827 | * file are held. A transaction has been started and an inplace reservation | ||
828 | * is held, as well. | ||
829 | * | ||
830 | * Returns: An inode | ||
831 | */ | 662 | */ |
832 | 663 | ||
833 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 664 | static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, |
834 | unsigned int mode, dev_t dev) | 665 | unsigned int mode, dev_t dev, const char *symname, |
666 | unsigned int size) | ||
835 | { | 667 | { |
668 | const struct qstr *name = &dentry->d_name; | ||
669 | struct gfs2_holder ghs[2]; | ||
836 | struct inode *inode = NULL; | 670 | struct inode *inode = NULL; |
837 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; | 671 | struct gfs2_inode *dip = GFS2_I(dir); |
838 | struct inode *dir = &dip->i_inode; | ||
839 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 672 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
840 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; | 673 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; |
841 | int error; | 674 | int error; |
@@ -843,10 +676,9 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
843 | struct buffer_head *bh = NULL; | 676 | struct buffer_head *bh = NULL; |
844 | 677 | ||
845 | if (!name->len || name->len > GFS2_FNAMESIZE) | 678 | if (!name->len || name->len > GFS2_FNAMESIZE) |
846 | return ERR_PTR(-ENAMETOOLONG); | 679 | return -ENAMETOOLONG; |
847 | 680 | ||
848 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); | 681 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
849 | error = gfs2_glock_nq(ghs); | ||
850 | if (error) | 682 | if (error) |
851 | goto fail; | 683 | goto fail; |
852 | 684 | ||
@@ -864,7 +696,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
864 | if (error) | 696 | if (error) |
865 | goto fail_gunlock; | 697 | goto fail_gunlock; |
866 | 698 | ||
867 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, &bh); | 699 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, symname, size, &bh); |
868 | if (error) | 700 | if (error) |
869 | goto fail_gunlock2; | 701 | goto fail_gunlock2; |
870 | 702 | ||
@@ -891,18 +723,852 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
891 | 723 | ||
892 | if (bh) | 724 | if (bh) |
893 | brelse(bh); | 725 | brelse(bh); |
894 | return inode; | 726 | |
727 | gfs2_trans_end(sdp); | ||
728 | if (dip->i_alloc->al_rgd) | ||
729 | gfs2_inplace_release(dip); | ||
730 | gfs2_quota_unlock(dip); | ||
731 | gfs2_alloc_put(dip); | ||
732 | gfs2_glock_dq_uninit_m(2, ghs); | ||
733 | mark_inode_dirty(inode); | ||
734 | d_instantiate(dentry, inode); | ||
735 | return 0; | ||
895 | 736 | ||
896 | fail_gunlock2: | 737 | fail_gunlock2: |
897 | gfs2_glock_dq_uninit(ghs + 1); | 738 | gfs2_glock_dq_uninit(ghs + 1); |
898 | if (inode && !IS_ERR(inode)) | 739 | if (inode && !IS_ERR(inode)) |
899 | iput(inode); | 740 | iput(inode); |
900 | fail_gunlock: | 741 | fail_gunlock: |
901 | gfs2_glock_dq(ghs); | 742 | gfs2_glock_dq_uninit(ghs); |
902 | fail: | 743 | fail: |
903 | if (bh) | 744 | if (bh) |
904 | brelse(bh); | 745 | brelse(bh); |
905 | return ERR_PTR(error); | 746 | return error; |
747 | } | ||
748 | |||
749 | /** | ||
750 | * gfs2_create - Create a file | ||
751 | * @dir: The directory in which to create the file | ||
752 | * @dentry: The dentry of the new file | ||
753 | * @mode: The mode of the new file | ||
754 | * | ||
755 | * Returns: errno | ||
756 | */ | ||
757 | |||
758 | static int gfs2_create(struct inode *dir, struct dentry *dentry, | ||
759 | int mode, struct nameidata *nd) | ||
760 | { | ||
761 | struct inode *inode; | ||
762 | int ret; | ||
763 | |||
764 | for (;;) { | ||
765 | ret = gfs2_create_inode(dir, dentry, S_IFREG | mode, 0, NULL, 0); | ||
766 | if (ret != -EEXIST || (nd && (nd->flags & LOOKUP_EXCL))) | ||
767 | return ret; | ||
768 | |||
769 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); | ||
770 | if (inode) { | ||
771 | if (!IS_ERR(inode)) | ||
772 | break; | ||
773 | return PTR_ERR(inode); | ||
774 | } | ||
775 | } | ||
776 | |||
777 | d_instantiate(dentry, inode); | ||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | /** | ||
782 | * gfs2_lookup - Look up a filename in a directory and return its inode | ||
783 | * @dir: The directory inode | ||
784 | * @dentry: The dentry of the new inode | ||
785 | * @nd: passed from Linux VFS, ignored by us | ||
786 | * | ||
787 | * Called by the VFS layer. Lock dir and call gfs2_lookupi() | ||
788 | * | ||
789 | * Returns: errno | ||
790 | */ | ||
791 | |||
792 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, | ||
793 | struct nameidata *nd) | ||
794 | { | ||
795 | struct inode *inode = NULL; | ||
796 | |||
797 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); | ||
798 | if (inode && IS_ERR(inode)) | ||
799 | return ERR_CAST(inode); | ||
800 | |||
801 | if (inode) { | ||
802 | struct gfs2_glock *gl = GFS2_I(inode)->i_gl; | ||
803 | struct gfs2_holder gh; | ||
804 | int error; | ||
805 | error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | ||
806 | if (error) { | ||
807 | iput(inode); | ||
808 | return ERR_PTR(error); | ||
809 | } | ||
810 | gfs2_glock_dq_uninit(&gh); | ||
811 | return d_splice_alias(inode, dentry); | ||
812 | } | ||
813 | d_add(dentry, inode); | ||
814 | |||
815 | return NULL; | ||
816 | } | ||
817 | |||
818 | /** | ||
819 | * gfs2_link - Link to a file | ||
820 | * @old_dentry: The inode to link | ||
821 | * @dir: Add link to this directory | ||
822 | * @dentry: The name of the link | ||
823 | * | ||
824 | * Link the inode in "old_dentry" into the directory "dir" with the | ||
825 | * name in "dentry". | ||
826 | * | ||
827 | * Returns: errno | ||
828 | */ | ||
829 | |||
830 | static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | ||
831 | struct dentry *dentry) | ||
832 | { | ||
833 | struct gfs2_inode *dip = GFS2_I(dir); | ||
834 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
835 | struct inode *inode = old_dentry->d_inode; | ||
836 | struct gfs2_inode *ip = GFS2_I(inode); | ||
837 | struct gfs2_holder ghs[2]; | ||
838 | struct buffer_head *dibh; | ||
839 | int alloc_required; | ||
840 | int error; | ||
841 | |||
842 | if (S_ISDIR(inode->i_mode)) | ||
843 | return -EPERM; | ||
844 | |||
845 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | ||
846 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | ||
847 | |||
848 | error = gfs2_glock_nq(ghs); /* parent */ | ||
849 | if (error) | ||
850 | goto out_parent; | ||
851 | |||
852 | error = gfs2_glock_nq(ghs + 1); /* child */ | ||
853 | if (error) | ||
854 | goto out_child; | ||
855 | |||
856 | error = -ENOENT; | ||
857 | if (inode->i_nlink == 0) | ||
858 | goto out_gunlock; | ||
859 | |||
860 | error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC, 0); | ||
861 | if (error) | ||
862 | goto out_gunlock; | ||
863 | |||
864 | error = gfs2_dir_check(dir, &dentry->d_name, NULL); | ||
865 | switch (error) { | ||
866 | case -ENOENT: | ||
867 | break; | ||
868 | case 0: | ||
869 | error = -EEXIST; | ||
870 | default: | ||
871 | goto out_gunlock; | ||
872 | } | ||
873 | |||
874 | error = -EINVAL; | ||
875 | if (!dip->i_inode.i_nlink) | ||
876 | goto out_gunlock; | ||
877 | error = -EFBIG; | ||
878 | if (dip->i_entries == (u32)-1) | ||
879 | goto out_gunlock; | ||
880 | error = -EPERM; | ||
881 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | ||
882 | goto out_gunlock; | ||
883 | error = -EINVAL; | ||
884 | if (!ip->i_inode.i_nlink) | ||
885 | goto out_gunlock; | ||
886 | error = -EMLINK; | ||
887 | if (ip->i_inode.i_nlink == (u32)-1) | ||
888 | goto out_gunlock; | ||
889 | |||
890 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); | ||
891 | if (error < 0) | ||
892 | goto out_gunlock; | ||
893 | error = 0; | ||
894 | |||
895 | if (alloc_required) { | ||
896 | struct gfs2_alloc *al = gfs2_alloc_get(dip); | ||
897 | if (!al) { | ||
898 | error = -ENOMEM; | ||
899 | goto out_gunlock; | ||
900 | } | ||
901 | |||
902 | error = gfs2_quota_lock_check(dip); | ||
903 | if (error) | ||
904 | goto out_alloc; | ||
905 | |||
906 | al->al_requested = sdp->sd_max_dirres; | ||
907 | |||
908 | error = gfs2_inplace_reserve(dip); | ||
909 | if (error) | ||
910 | goto out_gunlock_q; | ||
911 | |||
912 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | ||
913 | gfs2_rg_blocks(al) + | ||
914 | 2 * RES_DINODE + RES_STATFS + | ||
915 | RES_QUOTA, 0); | ||
916 | if (error) | ||
917 | goto out_ipres; | ||
918 | } else { | ||
919 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF, 0); | ||
920 | if (error) | ||
921 | goto out_ipres; | ||
922 | } | ||
923 | |||
924 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
925 | if (error) | ||
926 | goto out_end_trans; | ||
927 | |||
928 | error = gfs2_dir_add(dir, &dentry->d_name, ip); | ||
929 | if (error) | ||
930 | goto out_brelse; | ||
931 | |||
932 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
933 | inc_nlink(&ip->i_inode); | ||
934 | ip->i_inode.i_ctime = CURRENT_TIME; | ||
935 | gfs2_dinode_out(ip, dibh->b_data); | ||
936 | mark_inode_dirty(&ip->i_inode); | ||
937 | |||
938 | out_brelse: | ||
939 | brelse(dibh); | ||
940 | out_end_trans: | ||
941 | gfs2_trans_end(sdp); | ||
942 | out_ipres: | ||
943 | if (alloc_required) | ||
944 | gfs2_inplace_release(dip); | ||
945 | out_gunlock_q: | ||
946 | if (alloc_required) | ||
947 | gfs2_quota_unlock(dip); | ||
948 | out_alloc: | ||
949 | if (alloc_required) | ||
950 | gfs2_alloc_put(dip); | ||
951 | out_gunlock: | ||
952 | gfs2_glock_dq(ghs + 1); | ||
953 | out_child: | ||
954 | gfs2_glock_dq(ghs); | ||
955 | out_parent: | ||
956 | gfs2_holder_uninit(ghs); | ||
957 | gfs2_holder_uninit(ghs + 1); | ||
958 | if (!error) { | ||
959 | ihold(inode); | ||
960 | d_instantiate(dentry, inode); | ||
961 | mark_inode_dirty(inode); | ||
962 | } | ||
963 | return error; | ||
964 | } | ||
965 | |||
966 | /* | ||
967 | * gfs2_unlink_ok - check to see that a inode is still in a directory | ||
968 | * @dip: the directory | ||
969 | * @name: the name of the file | ||
970 | * @ip: the inode | ||
971 | * | ||
972 | * Assumes that the lock on (at least) @dip is held. | ||
973 | * | ||
974 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | ||
975 | */ | ||
976 | |||
977 | static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
978 | const struct gfs2_inode *ip) | ||
979 | { | ||
980 | int error; | ||
981 | |||
982 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | ||
983 | return -EPERM; | ||
984 | |||
985 | if ((dip->i_inode.i_mode & S_ISVTX) && | ||
986 | dip->i_inode.i_uid != current_fsuid() && | ||
987 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | ||
988 | return -EPERM; | ||
989 | |||
990 | if (IS_APPEND(&dip->i_inode)) | ||
991 | return -EPERM; | ||
992 | |||
993 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC, 0); | ||
994 | if (error) | ||
995 | return error; | ||
996 | |||
997 | error = gfs2_dir_check(&dip->i_inode, name, ip); | ||
998 | if (error) | ||
999 | return error; | ||
1000 | |||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | /** | ||
1005 | * gfs2_unlink_inode - Removes an inode from its parent dir and unlinks it | ||
1006 | * @dip: The parent directory | ||
1007 | * @name: The name of the entry in the parent directory | ||
1008 | * @bh: The inode buffer for the inode to be removed | ||
1009 | * @inode: The inode to be removed | ||
1010 | * | ||
1011 | * Called with all the locks and in a transaction. This will only be | ||
1012 | * called for a directory after it has been checked to ensure it is empty. | ||
1013 | * | ||
1014 | * Returns: 0 on success, or an error | ||
1015 | */ | ||
1016 | |||
1017 | static int gfs2_unlink_inode(struct gfs2_inode *dip, | ||
1018 | const struct dentry *dentry, | ||
1019 | struct buffer_head *bh) | ||
1020 | { | ||
1021 | struct inode *inode = dentry->d_inode; | ||
1022 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1023 | int error; | ||
1024 | |||
1025 | error = gfs2_dir_del(dip, dentry); | ||
1026 | if (error) | ||
1027 | return error; | ||
1028 | |||
1029 | ip->i_entries = 0; | ||
1030 | inode->i_ctime = CURRENT_TIME; | ||
1031 | if (S_ISDIR(inode->i_mode)) | ||
1032 | clear_nlink(inode); | ||
1033 | else | ||
1034 | drop_nlink(inode); | ||
1035 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | ||
1036 | gfs2_dinode_out(ip, bh->b_data); | ||
1037 | mark_inode_dirty(inode); | ||
1038 | if (inode->i_nlink == 0) | ||
1039 | gfs2_unlink_di(inode); | ||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | |||
1044 | /** | ||
1045 | * gfs2_unlink - Unlink an inode (this does rmdir as well) | ||
1046 | * @dir: The inode of the directory containing the inode to unlink | ||
1047 | * @dentry: The file itself | ||
1048 | * | ||
1049 | * This routine uses the type of the inode as a flag to figure out | ||
1050 | * whether this is an unlink or an rmdir. | ||
1051 | * | ||
1052 | * Returns: errno | ||
1053 | */ | ||
1054 | |||
1055 | static int gfs2_unlink(struct inode *dir, struct dentry *dentry) | ||
1056 | { | ||
1057 | struct gfs2_inode *dip = GFS2_I(dir); | ||
1058 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
1059 | struct inode *inode = dentry->d_inode; | ||
1060 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1061 | struct buffer_head *bh; | ||
1062 | struct gfs2_holder ghs[3]; | ||
1063 | struct gfs2_rgrpd *rgd; | ||
1064 | struct gfs2_holder ri_gh; | ||
1065 | int error; | ||
1066 | |||
1067 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
1068 | if (error) | ||
1069 | return error; | ||
1070 | |||
1071 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | ||
1072 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | ||
1073 | |||
1074 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | ||
1075 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | ||
1076 | |||
1077 | |||
1078 | error = gfs2_glock_nq(ghs); /* parent */ | ||
1079 | if (error) | ||
1080 | goto out_parent; | ||
1081 | |||
1082 | error = gfs2_glock_nq(ghs + 1); /* child */ | ||
1083 | if (error) | ||
1084 | goto out_child; | ||
1085 | |||
1086 | error = -ENOENT; | ||
1087 | if (inode->i_nlink == 0) | ||
1088 | goto out_rgrp; | ||
1089 | |||
1090 | if (S_ISDIR(inode->i_mode)) { | ||
1091 | error = -ENOTEMPTY; | ||
1092 | if (ip->i_entries > 2 || inode->i_nlink > 2) | ||
1093 | goto out_rgrp; | ||
1094 | } | ||
1095 | |||
1096 | error = gfs2_glock_nq(ghs + 2); /* rgrp */ | ||
1097 | if (error) | ||
1098 | goto out_rgrp; | ||
1099 | |||
1100 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); | ||
1101 | if (error) | ||
1102 | goto out_gunlock; | ||
1103 | |||
1104 | error = gfs2_trans_begin(sdp, 2*RES_DINODE + 3*RES_LEAF + RES_RG_BIT, 0); | ||
1105 | if (error) | ||
1106 | goto out_gunlock; | ||
1107 | |||
1108 | error = gfs2_meta_inode_buffer(ip, &bh); | ||
1109 | if (error) | ||
1110 | goto out_end_trans; | ||
1111 | |||
1112 | error = gfs2_unlink_inode(dip, dentry, bh); | ||
1113 | brelse(bh); | ||
1114 | |||
1115 | out_end_trans: | ||
1116 | gfs2_trans_end(sdp); | ||
1117 | out_gunlock: | ||
1118 | gfs2_glock_dq(ghs + 2); | ||
1119 | out_rgrp: | ||
1120 | gfs2_holder_uninit(ghs + 2); | ||
1121 | gfs2_glock_dq(ghs + 1); | ||
1122 | out_child: | ||
1123 | gfs2_holder_uninit(ghs + 1); | ||
1124 | gfs2_glock_dq(ghs); | ||
1125 | out_parent: | ||
1126 | gfs2_holder_uninit(ghs); | ||
1127 | gfs2_glock_dq_uninit(&ri_gh); | ||
1128 | return error; | ||
1129 | } | ||
1130 | |||
1131 | /** | ||
1132 | * gfs2_symlink - Create a symlink | ||
1133 | * @dir: The directory to create the symlink in | ||
1134 | * @dentry: The dentry to put the symlink in | ||
1135 | * @symname: The thing which the link points to | ||
1136 | * | ||
1137 | * Returns: errno | ||
1138 | */ | ||
1139 | |||
1140 | static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | ||
1141 | const char *symname) | ||
1142 | { | ||
1143 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
1144 | unsigned int size; | ||
1145 | |||
1146 | size = strlen(symname); | ||
1147 | if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1) | ||
1148 | return -ENAMETOOLONG; | ||
1149 | |||
1150 | return gfs2_create_inode(dir, dentry, S_IFLNK | S_IRWXUGO, 0, symname, size); | ||
1151 | } | ||
1152 | |||
1153 | /** | ||
1154 | * gfs2_mkdir - Make a directory | ||
1155 | * @dir: The parent directory of the new one | ||
1156 | * @dentry: The dentry of the new directory | ||
1157 | * @mode: The mode of the new directory | ||
1158 | * | ||
1159 | * Returns: errno | ||
1160 | */ | ||
1161 | |||
1162 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | ||
1163 | { | ||
1164 | return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, 0); | ||
1165 | } | ||
1166 | |||
1167 | /** | ||
1168 | * gfs2_mknod - Make a special file | ||
1169 | * @dir: The directory in which the special file will reside | ||
1170 | * @dentry: The dentry of the special file | ||
1171 | * @mode: The mode of the special file | ||
1172 | * @dev: The device specification of the special file | ||
1173 | * | ||
1174 | */ | ||
1175 | |||
1176 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, | ||
1177 | dev_t dev) | ||
1178 | { | ||
1179 | return gfs2_create_inode(dir, dentry, mode, dev, NULL, 0); | ||
1180 | } | ||
1181 | |||
1182 | /* | ||
1183 | * gfs2_ok_to_move - check if it's ok to move a directory to another directory | ||
1184 | * @this: move this | ||
1185 | * @to: to here | ||
1186 | * | ||
1187 | * Follow @to back to the root and make sure we don't encounter @this | ||
1188 | * Assumes we already hold the rename lock. | ||
1189 | * | ||
1190 | * Returns: errno | ||
1191 | */ | ||
1192 | |||
1193 | static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) | ||
1194 | { | ||
1195 | struct inode *dir = &to->i_inode; | ||
1196 | struct super_block *sb = dir->i_sb; | ||
1197 | struct inode *tmp; | ||
1198 | int error = 0; | ||
1199 | |||
1200 | igrab(dir); | ||
1201 | |||
1202 | for (;;) { | ||
1203 | if (dir == &this->i_inode) { | ||
1204 | error = -EINVAL; | ||
1205 | break; | ||
1206 | } | ||
1207 | if (dir == sb->s_root->d_inode) { | ||
1208 | error = 0; | ||
1209 | break; | ||
1210 | } | ||
1211 | |||
1212 | tmp = gfs2_lookupi(dir, &gfs2_qdotdot, 1); | ||
1213 | if (IS_ERR(tmp)) { | ||
1214 | error = PTR_ERR(tmp); | ||
1215 | break; | ||
1216 | } | ||
1217 | |||
1218 | iput(dir); | ||
1219 | dir = tmp; | ||
1220 | } | ||
1221 | |||
1222 | iput(dir); | ||
1223 | |||
1224 | return error; | ||
1225 | } | ||
1226 | |||
1227 | /** | ||
1228 | * gfs2_rename - Rename a file | ||
1229 | * @odir: Parent directory of old file name | ||
1230 | * @odentry: The old dentry of the file | ||
1231 | * @ndir: Parent directory of new file name | ||
1232 | * @ndentry: The new dentry of the file | ||
1233 | * | ||
1234 | * Returns: errno | ||
1235 | */ | ||
1236 | |||
1237 | static int gfs2_rename(struct inode *odir, struct dentry *odentry, | ||
1238 | struct inode *ndir, struct dentry *ndentry) | ||
1239 | { | ||
1240 | struct gfs2_inode *odip = GFS2_I(odir); | ||
1241 | struct gfs2_inode *ndip = GFS2_I(ndir); | ||
1242 | struct gfs2_inode *ip = GFS2_I(odentry->d_inode); | ||
1243 | struct gfs2_inode *nip = NULL; | ||
1244 | struct gfs2_sbd *sdp = GFS2_SB(odir); | ||
1245 | struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, }, ri_gh; | ||
1246 | struct gfs2_rgrpd *nrgd; | ||
1247 | unsigned int num_gh; | ||
1248 | int dir_rename = 0; | ||
1249 | int alloc_required = 0; | ||
1250 | unsigned int x; | ||
1251 | int error; | ||
1252 | |||
1253 | if (ndentry->d_inode) { | ||
1254 | nip = GFS2_I(ndentry->d_inode); | ||
1255 | if (ip == nip) | ||
1256 | return 0; | ||
1257 | } | ||
1258 | |||
1259 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
1260 | if (error) | ||
1261 | return error; | ||
1262 | |||
1263 | if (odip != ndip) { | ||
1264 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, | ||
1265 | 0, &r_gh); | ||
1266 | if (error) | ||
1267 | goto out; | ||
1268 | |||
1269 | if (S_ISDIR(ip->i_inode.i_mode)) { | ||
1270 | dir_rename = 1; | ||
1271 | /* don't move a dirctory into it's subdir */ | ||
1272 | error = gfs2_ok_to_move(ip, ndip); | ||
1273 | if (error) | ||
1274 | goto out_gunlock_r; | ||
1275 | } | ||
1276 | } | ||
1277 | |||
1278 | num_gh = 1; | ||
1279 | gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | ||
1280 | if (odip != ndip) { | ||
1281 | gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); | ||
1282 | num_gh++; | ||
1283 | } | ||
1284 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); | ||
1285 | num_gh++; | ||
1286 | |||
1287 | if (nip) { | ||
1288 | gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); | ||
1289 | num_gh++; | ||
1290 | /* grab the resource lock for unlink flag twiddling | ||
1291 | * this is the case of the target file already existing | ||
1292 | * so we unlink before doing the rename | ||
1293 | */ | ||
1294 | nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr); | ||
1295 | if (nrgd) | ||
1296 | gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); | ||
1297 | } | ||
1298 | |||
1299 | for (x = 0; x < num_gh; x++) { | ||
1300 | error = gfs2_glock_nq(ghs + x); | ||
1301 | if (error) | ||
1302 | goto out_gunlock; | ||
1303 | } | ||
1304 | |||
1305 | error = -ENOENT; | ||
1306 | if (ip->i_inode.i_nlink == 0) | ||
1307 | goto out_gunlock; | ||
1308 | |||
1309 | /* Check out the old directory */ | ||
1310 | |||
1311 | error = gfs2_unlink_ok(odip, &odentry->d_name, ip); | ||
1312 | if (error) | ||
1313 | goto out_gunlock; | ||
1314 | |||
1315 | /* Check out the new directory */ | ||
1316 | |||
1317 | if (nip) { | ||
1318 | error = gfs2_unlink_ok(ndip, &ndentry->d_name, nip); | ||
1319 | if (error) | ||
1320 | goto out_gunlock; | ||
1321 | |||
1322 | if (nip->i_inode.i_nlink == 0) { | ||
1323 | error = -EAGAIN; | ||
1324 | goto out_gunlock; | ||
1325 | } | ||
1326 | |||
1327 | if (S_ISDIR(nip->i_inode.i_mode)) { | ||
1328 | if (nip->i_entries < 2) { | ||
1329 | gfs2_consist_inode(nip); | ||
1330 | error = -EIO; | ||
1331 | goto out_gunlock; | ||
1332 | } | ||
1333 | if (nip->i_entries > 2) { | ||
1334 | error = -ENOTEMPTY; | ||
1335 | goto out_gunlock; | ||
1336 | } | ||
1337 | } | ||
1338 | } else { | ||
1339 | error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC, 0); | ||
1340 | if (error) | ||
1341 | goto out_gunlock; | ||
1342 | |||
1343 | error = gfs2_dir_check(ndir, &ndentry->d_name, NULL); | ||
1344 | switch (error) { | ||
1345 | case -ENOENT: | ||
1346 | error = 0; | ||
1347 | break; | ||
1348 | case 0: | ||
1349 | error = -EEXIST; | ||
1350 | default: | ||
1351 | goto out_gunlock; | ||
1352 | }; | ||
1353 | |||
1354 | if (odip != ndip) { | ||
1355 | if (!ndip->i_inode.i_nlink) { | ||
1356 | error = -ENOENT; | ||
1357 | goto out_gunlock; | ||
1358 | } | ||
1359 | if (ndip->i_entries == (u32)-1) { | ||
1360 | error = -EFBIG; | ||
1361 | goto out_gunlock; | ||
1362 | } | ||
1363 | if (S_ISDIR(ip->i_inode.i_mode) && | ||
1364 | ndip->i_inode.i_nlink == (u32)-1) { | ||
1365 | error = -EMLINK; | ||
1366 | goto out_gunlock; | ||
1367 | } | ||
1368 | } | ||
1369 | } | ||
1370 | |||
1371 | /* Check out the dir to be renamed */ | ||
1372 | |||
1373 | if (dir_rename) { | ||
1374 | error = gfs2_permission(odentry->d_inode, MAY_WRITE, 0); | ||
1375 | if (error) | ||
1376 | goto out_gunlock; | ||
1377 | } | ||
1378 | |||
1379 | if (nip == NULL) | ||
1380 | alloc_required = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); | ||
1381 | error = alloc_required; | ||
1382 | if (error < 0) | ||
1383 | goto out_gunlock; | ||
1384 | error = 0; | ||
1385 | |||
1386 | if (alloc_required) { | ||
1387 | struct gfs2_alloc *al = gfs2_alloc_get(ndip); | ||
1388 | if (!al) { | ||
1389 | error = -ENOMEM; | ||
1390 | goto out_gunlock; | ||
1391 | } | ||
1392 | |||
1393 | error = gfs2_quota_lock_check(ndip); | ||
1394 | if (error) | ||
1395 | goto out_alloc; | ||
1396 | |||
1397 | al->al_requested = sdp->sd_max_dirres; | ||
1398 | |||
1399 | error = gfs2_inplace_reserve_ri(ndip); | ||
1400 | if (error) | ||
1401 | goto out_gunlock_q; | ||
1402 | |||
1403 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | ||
1404 | gfs2_rg_blocks(al) + | ||
1405 | 4 * RES_DINODE + 4 * RES_LEAF + | ||
1406 | RES_STATFS + RES_QUOTA + 4, 0); | ||
1407 | if (error) | ||
1408 | goto out_ipreserv; | ||
1409 | } else { | ||
1410 | error = gfs2_trans_begin(sdp, 4 * RES_DINODE + | ||
1411 | 5 * RES_LEAF + 4, 0); | ||
1412 | if (error) | ||
1413 | goto out_gunlock; | ||
1414 | } | ||
1415 | |||
1416 | /* Remove the target file, if it exists */ | ||
1417 | |||
1418 | if (nip) { | ||
1419 | struct buffer_head *bh; | ||
1420 | error = gfs2_meta_inode_buffer(nip, &bh); | ||
1421 | if (error) | ||
1422 | goto out_end_trans; | ||
1423 | error = gfs2_unlink_inode(ndip, ndentry, bh); | ||
1424 | brelse(bh); | ||
1425 | } | ||
1426 | |||
1427 | if (dir_rename) { | ||
1428 | error = gfs2_dir_mvino(ip, &gfs2_qdotdot, ndip, DT_DIR); | ||
1429 | if (error) | ||
1430 | goto out_end_trans; | ||
1431 | } else { | ||
1432 | struct buffer_head *dibh; | ||
1433 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
1434 | if (error) | ||
1435 | goto out_end_trans; | ||
1436 | ip->i_inode.i_ctime = CURRENT_TIME; | ||
1437 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
1438 | gfs2_dinode_out(ip, dibh->b_data); | ||
1439 | brelse(dibh); | ||
1440 | } | ||
1441 | |||
1442 | error = gfs2_dir_del(odip, odentry); | ||
1443 | if (error) | ||
1444 | goto out_end_trans; | ||
1445 | |||
1446 | error = gfs2_dir_add(ndir, &ndentry->d_name, ip); | ||
1447 | if (error) | ||
1448 | goto out_end_trans; | ||
1449 | |||
1450 | out_end_trans: | ||
1451 | gfs2_trans_end(sdp); | ||
1452 | out_ipreserv: | ||
1453 | if (alloc_required) | ||
1454 | gfs2_inplace_release(ndip); | ||
1455 | out_gunlock_q: | ||
1456 | if (alloc_required) | ||
1457 | gfs2_quota_unlock(ndip); | ||
1458 | out_alloc: | ||
1459 | if (alloc_required) | ||
1460 | gfs2_alloc_put(ndip); | ||
1461 | out_gunlock: | ||
1462 | while (x--) { | ||
1463 | gfs2_glock_dq(ghs + x); | ||
1464 | gfs2_holder_uninit(ghs + x); | ||
1465 | } | ||
1466 | out_gunlock_r: | ||
1467 | if (r_gh.gh_gl) | ||
1468 | gfs2_glock_dq_uninit(&r_gh); | ||
1469 | out: | ||
1470 | gfs2_glock_dq_uninit(&ri_gh); | ||
1471 | return error; | ||
1472 | } | ||
1473 | |||
1474 | /** | ||
1475 | * gfs2_follow_link - Follow a symbolic link | ||
1476 | * @dentry: The dentry of the link | ||
1477 | * @nd: Data that we pass to vfs_follow_link() | ||
1478 | * | ||
1479 | * This can handle symlinks of any size. | ||
1480 | * | ||
1481 | * Returns: 0 on success or error code | ||
1482 | */ | ||
1483 | |||
1484 | static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) | ||
1485 | { | ||
1486 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
1487 | struct gfs2_holder i_gh; | ||
1488 | struct buffer_head *dibh; | ||
1489 | unsigned int size; | ||
1490 | char *buf; | ||
1491 | int error; | ||
1492 | |||
1493 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); | ||
1494 | error = gfs2_glock_nq(&i_gh); | ||
1495 | if (error) { | ||
1496 | gfs2_holder_uninit(&i_gh); | ||
1497 | nd_set_link(nd, ERR_PTR(error)); | ||
1498 | return NULL; | ||
1499 | } | ||
1500 | |||
1501 | size = (unsigned int)i_size_read(&ip->i_inode); | ||
1502 | if (size == 0) { | ||
1503 | gfs2_consist_inode(ip); | ||
1504 | buf = ERR_PTR(-EIO); | ||
1505 | goto out; | ||
1506 | } | ||
1507 | |||
1508 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
1509 | if (error) { | ||
1510 | buf = ERR_PTR(error); | ||
1511 | goto out; | ||
1512 | } | ||
1513 | |||
1514 | buf = kzalloc(size + 1, GFP_NOFS); | ||
1515 | if (!buf) | ||
1516 | buf = ERR_PTR(-ENOMEM); | ||
1517 | else | ||
1518 | memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), size); | ||
1519 | brelse(dibh); | ||
1520 | out: | ||
1521 | gfs2_glock_dq_uninit(&i_gh); | ||
1522 | nd_set_link(nd, buf); | ||
1523 | return NULL; | ||
1524 | } | ||
1525 | |||
1526 | static void gfs2_put_link(struct dentry *dentry, struct nameidata *nd, void *p) | ||
1527 | { | ||
1528 | char *s = nd_get_link(nd); | ||
1529 | if (!IS_ERR(s)) | ||
1530 | kfree(s); | ||
1531 | } | ||
1532 | |||
1533 | /** | ||
1534 | * gfs2_permission - | ||
1535 | * @inode: The inode | ||
1536 | * @mask: The mask to be tested | ||
1537 | * @flags: Indicates whether this is an RCU path walk or not | ||
1538 | * | ||
1539 | * This may be called from the VFS directly, or from within GFS2 with the | ||
1540 | * inode locked, so we look to see if the glock is already locked and only | ||
1541 | * lock the glock if its not already been done. | ||
1542 | * | ||
1543 | * Returns: errno | ||
1544 | */ | ||
1545 | |||
1546 | int gfs2_permission(struct inode *inode, int mask, unsigned int flags) | ||
1547 | { | ||
1548 | struct gfs2_inode *ip; | ||
1549 | struct gfs2_holder i_gh; | ||
1550 | int error; | ||
1551 | int unlock = 0; | ||
1552 | |||
1553 | |||
1554 | ip = GFS2_I(inode); | ||
1555 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { | ||
1556 | if (flags & IPERM_FLAG_RCU) | ||
1557 | return -ECHILD; | ||
1558 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | ||
1559 | if (error) | ||
1560 | return error; | ||
1561 | unlock = 1; | ||
1562 | } | ||
1563 | |||
1564 | if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) | ||
1565 | error = -EACCES; | ||
1566 | else | ||
1567 | error = generic_permission(inode, mask, flags, gfs2_check_acl); | ||
1568 | if (unlock) | ||
1569 | gfs2_glock_dq_uninit(&i_gh); | ||
1570 | |||
1571 | return error; | ||
906 | } | 1572 | } |
907 | 1573 | ||
908 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1574 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
@@ -928,8 +1594,6 @@ static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | |||
928 | * @ip: | 1594 | * @ip: |
929 | * @attr: | 1595 | * @attr: |
930 | * | 1596 | * |
931 | * Called with a reference on the vnode. | ||
932 | * | ||
933 | * Returns: errno | 1597 | * Returns: errno |
934 | */ | 1598 | */ |
935 | 1599 | ||
@@ -949,60 +1613,280 @@ int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | |||
949 | return error; | 1613 | return error; |
950 | } | 1614 | } |
951 | 1615 | ||
952 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | 1616 | static int setattr_chown(struct inode *inode, struct iattr *attr) |
953 | { | 1617 | { |
954 | struct gfs2_dinode *str = buf; | 1618 | struct gfs2_inode *ip = GFS2_I(inode); |
955 | 1619 | struct gfs2_sbd *sdp = GFS2_SB(inode); | |
956 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | 1620 | u32 ouid, ogid, nuid, ngid; |
957 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); | 1621 | int error; |
958 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); | 1622 | |
959 | str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); | 1623 | ouid = inode->i_uid; |
960 | str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | 1624 | ogid = inode->i_gid; |
961 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); | 1625 | nuid = attr->ia_uid; |
962 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); | 1626 | ngid = attr->ia_gid; |
963 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | 1627 | |
964 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | 1628 | if (!(attr->ia_valid & ATTR_UID) || ouid == nuid) |
965 | str->di_size = cpu_to_be64(i_size_read(&ip->i_inode)); | 1629 | ouid = nuid = NO_QUOTA_CHANGE; |
966 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); | 1630 | if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) |
967 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | 1631 | ogid = ngid = NO_QUOTA_CHANGE; |
968 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); | 1632 | |
969 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); | 1633 | if (!gfs2_alloc_get(ip)) |
970 | 1634 | return -ENOMEM; | |
971 | str->di_goal_meta = cpu_to_be64(ip->i_goal); | 1635 | |
972 | str->di_goal_data = cpu_to_be64(ip->i_goal); | 1636 | error = gfs2_quota_lock(ip, nuid, ngid); |
973 | str->di_generation = cpu_to_be64(ip->i_generation); | 1637 | if (error) |
974 | 1638 | goto out_alloc; | |
975 | str->di_flags = cpu_to_be32(ip->i_diskflags); | 1639 | |
976 | str->di_height = cpu_to_be16(ip->i_height); | 1640 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
977 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | 1641 | error = gfs2_quota_check(ip, nuid, ngid); |
978 | !(ip->i_diskflags & GFS2_DIF_EXHASH) ? | 1642 | if (error) |
979 | GFS2_FORMAT_DE : 0); | 1643 | goto out_gunlock_q; |
980 | str->di_depth = cpu_to_be16(ip->i_depth); | 1644 | } |
981 | str->di_entries = cpu_to_be32(ip->i_entries); | 1645 | |
982 | 1646 | error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_QUOTA, 0); | |
983 | str->di_eattr = cpu_to_be64(ip->i_eattr); | 1647 | if (error) |
984 | str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); | 1648 | goto out_gunlock_q; |
985 | str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); | 1649 | |
986 | str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); | 1650 | error = gfs2_setattr_simple(ip, attr); |
987 | } | 1651 | if (error) |
988 | 1652 | goto out_end_trans; | |
989 | void gfs2_dinode_print(const struct gfs2_inode *ip) | 1653 | |
990 | { | 1654 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
991 | printk(KERN_INFO " no_formal_ino = %llu\n", | 1655 | u64 blocks = gfs2_get_inode_blocks(&ip->i_inode); |
992 | (unsigned long long)ip->i_no_formal_ino); | 1656 | gfs2_quota_change(ip, -blocks, ouid, ogid); |
993 | printk(KERN_INFO " no_addr = %llu\n", | 1657 | gfs2_quota_change(ip, blocks, nuid, ngid); |
994 | (unsigned long long)ip->i_no_addr); | 1658 | } |
995 | printk(KERN_INFO " i_size = %llu\n", | 1659 | |
996 | (unsigned long long)i_size_read(&ip->i_inode)); | 1660 | out_end_trans: |
997 | printk(KERN_INFO " blocks = %llu\n", | 1661 | gfs2_trans_end(sdp); |
998 | (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode)); | 1662 | out_gunlock_q: |
999 | printk(KERN_INFO " i_goal = %llu\n", | 1663 | gfs2_quota_unlock(ip); |
1000 | (unsigned long long)ip->i_goal); | 1664 | out_alloc: |
1001 | printk(KERN_INFO " i_diskflags = 0x%.8X\n", ip->i_diskflags); | 1665 | gfs2_alloc_put(ip); |
1002 | printk(KERN_INFO " i_height = %u\n", ip->i_height); | 1666 | return error; |
1003 | printk(KERN_INFO " i_depth = %u\n", ip->i_depth); | 1667 | } |
1004 | printk(KERN_INFO " i_entries = %u\n", ip->i_entries); | 1668 | |
1005 | printk(KERN_INFO " i_eattr = %llu\n", | 1669 | /** |
1006 | (unsigned long long)ip->i_eattr); | 1670 | * gfs2_setattr - Change attributes on an inode |
1671 | * @dentry: The dentry which is changing | ||
1672 | * @attr: The structure describing the change | ||
1673 | * | ||
1674 | * The VFS layer wants to change one or more of an inodes attributes. Write | ||
1675 | * that change out to disk. | ||
1676 | * | ||
1677 | * Returns: errno | ||
1678 | */ | ||
1679 | |||
1680 | static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) | ||
1681 | { | ||
1682 | struct inode *inode = dentry->d_inode; | ||
1683 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1684 | struct gfs2_holder i_gh; | ||
1685 | int error; | ||
1686 | |||
1687 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); | ||
1688 | if (error) | ||
1689 | return error; | ||
1690 | |||
1691 | error = -EPERM; | ||
1692 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | ||
1693 | goto out; | ||
1694 | |||
1695 | error = inode_change_ok(inode, attr); | ||
1696 | if (error) | ||
1697 | goto out; | ||
1698 | |||
1699 | if (attr->ia_valid & ATTR_SIZE) | ||
1700 | error = gfs2_setattr_size(inode, attr->ia_size); | ||
1701 | else if (attr->ia_valid & (ATTR_UID | ATTR_GID)) | ||
1702 | error = setattr_chown(inode, attr); | ||
1703 | else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode)) | ||
1704 | error = gfs2_acl_chmod(ip, attr); | ||
1705 | else | ||
1706 | error = gfs2_setattr_simple(ip, attr); | ||
1707 | |||
1708 | out: | ||
1709 | gfs2_glock_dq_uninit(&i_gh); | ||
1710 | if (!error) | ||
1711 | mark_inode_dirty(inode); | ||
1712 | return error; | ||
1713 | } | ||
1714 | |||
1715 | /** | ||
1716 | * gfs2_getattr - Read out an inode's attributes | ||
1717 | * @mnt: The vfsmount the inode is being accessed from | ||
1718 | * @dentry: The dentry to stat | ||
1719 | * @stat: The inode's stats | ||
1720 | * | ||
1721 | * This may be called from the VFS directly, or from within GFS2 with the | ||
1722 | * inode locked, so we look to see if the glock is already locked and only | ||
1723 | * lock the glock if its not already been done. Note that its the NFS | ||
1724 | * readdirplus operation which causes this to be called (from filldir) | ||
1725 | * with the glock already held. | ||
1726 | * | ||
1727 | * Returns: errno | ||
1728 | */ | ||
1729 | |||
1730 | static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
1731 | struct kstat *stat) | ||
1732 | { | ||
1733 | struct inode *inode = dentry->d_inode; | ||
1734 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1735 | struct gfs2_holder gh; | ||
1736 | int error; | ||
1737 | int unlock = 0; | ||
1738 | |||
1739 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { | ||
1740 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | ||
1741 | if (error) | ||
1742 | return error; | ||
1743 | unlock = 1; | ||
1744 | } | ||
1745 | |||
1746 | generic_fillattr(inode, stat); | ||
1747 | if (unlock) | ||
1748 | gfs2_glock_dq_uninit(&gh); | ||
1749 | |||
1750 | return 0; | ||
1751 | } | ||
1752 | |||
1753 | static int gfs2_setxattr(struct dentry *dentry, const char *name, | ||
1754 | const void *data, size_t size, int flags) | ||
1755 | { | ||
1756 | struct inode *inode = dentry->d_inode; | ||
1757 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1758 | struct gfs2_holder gh; | ||
1759 | int ret; | ||
1760 | |||
1761 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
1762 | ret = gfs2_glock_nq(&gh); | ||
1763 | if (ret == 0) { | ||
1764 | ret = generic_setxattr(dentry, name, data, size, flags); | ||
1765 | gfs2_glock_dq(&gh); | ||
1766 | } | ||
1767 | gfs2_holder_uninit(&gh); | ||
1768 | return ret; | ||
1769 | } | ||
1770 | |||
1771 | static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name, | ||
1772 | void *data, size_t size) | ||
1773 | { | ||
1774 | struct inode *inode = dentry->d_inode; | ||
1775 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1776 | struct gfs2_holder gh; | ||
1777 | int ret; | ||
1778 | |||
1779 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | ||
1780 | ret = gfs2_glock_nq(&gh); | ||
1781 | if (ret == 0) { | ||
1782 | ret = generic_getxattr(dentry, name, data, size); | ||
1783 | gfs2_glock_dq(&gh); | ||
1784 | } | ||
1785 | gfs2_holder_uninit(&gh); | ||
1786 | return ret; | ||
1787 | } | ||
1788 | |||
1789 | static int gfs2_removexattr(struct dentry *dentry, const char *name) | ||
1790 | { | ||
1791 | struct inode *inode = dentry->d_inode; | ||
1792 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1793 | struct gfs2_holder gh; | ||
1794 | int ret; | ||
1795 | |||
1796 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
1797 | ret = gfs2_glock_nq(&gh); | ||
1798 | if (ret == 0) { | ||
1799 | ret = generic_removexattr(dentry, name); | ||
1800 | gfs2_glock_dq(&gh); | ||
1801 | } | ||
1802 | gfs2_holder_uninit(&gh); | ||
1803 | return ret; | ||
1804 | } | ||
1805 | |||
1806 | static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | ||
1807 | u64 start, u64 len) | ||
1808 | { | ||
1809 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1810 | struct gfs2_holder gh; | ||
1811 | int ret; | ||
1812 | |||
1813 | ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); | ||
1814 | if (ret) | ||
1815 | return ret; | ||
1816 | |||
1817 | mutex_lock(&inode->i_mutex); | ||
1818 | |||
1819 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | ||
1820 | if (ret) | ||
1821 | goto out; | ||
1822 | |||
1823 | if (gfs2_is_stuffed(ip)) { | ||
1824 | u64 phys = ip->i_no_addr << inode->i_blkbits; | ||
1825 | u64 size = i_size_read(inode); | ||
1826 | u32 flags = FIEMAP_EXTENT_LAST|FIEMAP_EXTENT_NOT_ALIGNED| | ||
1827 | FIEMAP_EXTENT_DATA_INLINE; | ||
1828 | phys += sizeof(struct gfs2_dinode); | ||
1829 | phys += start; | ||
1830 | if (start + len > size) | ||
1831 | len = size - start; | ||
1832 | if (start < size) | ||
1833 | ret = fiemap_fill_next_extent(fieinfo, start, phys, | ||
1834 | len, flags); | ||
1835 | if (ret == 1) | ||
1836 | ret = 0; | ||
1837 | } else { | ||
1838 | ret = __generic_block_fiemap(inode, fieinfo, start, len, | ||
1839 | gfs2_block_map); | ||
1840 | } | ||
1841 | |||
1842 | gfs2_glock_dq_uninit(&gh); | ||
1843 | out: | ||
1844 | mutex_unlock(&inode->i_mutex); | ||
1845 | return ret; | ||
1007 | } | 1846 | } |
1008 | 1847 | ||
1848 | const struct inode_operations gfs2_file_iops = { | ||
1849 | .permission = gfs2_permission, | ||
1850 | .setattr = gfs2_setattr, | ||
1851 | .getattr = gfs2_getattr, | ||
1852 | .setxattr = gfs2_setxattr, | ||
1853 | .getxattr = gfs2_getxattr, | ||
1854 | .listxattr = gfs2_listxattr, | ||
1855 | .removexattr = gfs2_removexattr, | ||
1856 | .fiemap = gfs2_fiemap, | ||
1857 | }; | ||
1858 | |||
1859 | const struct inode_operations gfs2_dir_iops = { | ||
1860 | .create = gfs2_create, | ||
1861 | .lookup = gfs2_lookup, | ||
1862 | .link = gfs2_link, | ||
1863 | .unlink = gfs2_unlink, | ||
1864 | .symlink = gfs2_symlink, | ||
1865 | .mkdir = gfs2_mkdir, | ||
1866 | .rmdir = gfs2_unlink, | ||
1867 | .mknod = gfs2_mknod, | ||
1868 | .rename = gfs2_rename, | ||
1869 | .permission = gfs2_permission, | ||
1870 | .setattr = gfs2_setattr, | ||
1871 | .getattr = gfs2_getattr, | ||
1872 | .setxattr = gfs2_setxattr, | ||
1873 | .getxattr = gfs2_getxattr, | ||
1874 | .listxattr = gfs2_listxattr, | ||
1875 | .removexattr = gfs2_removexattr, | ||
1876 | .fiemap = gfs2_fiemap, | ||
1877 | }; | ||
1878 | |||
1879 | const struct inode_operations gfs2_symlink_iops = { | ||
1880 | .readlink = generic_readlink, | ||
1881 | .follow_link = gfs2_follow_link, | ||
1882 | .put_link = gfs2_put_link, | ||
1883 | .permission = gfs2_permission, | ||
1884 | .setattr = gfs2_setattr, | ||
1885 | .getattr = gfs2_getattr, | ||
1886 | .setxattr = gfs2_setxattr, | ||
1887 | .getxattr = gfs2_getxattr, | ||
1888 | .listxattr = gfs2_listxattr, | ||
1889 | .removexattr = gfs2_removexattr, | ||
1890 | .fiemap = gfs2_fiemap, | ||
1891 | }; | ||
1892 | |||
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 099ca305e518..31606076f701 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -102,22 +102,16 @@ extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, | |||
102 | extern struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, | 102 | extern struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, |
103 | u64 *no_formal_ino, | 103 | u64 *no_formal_ino, |
104 | unsigned int blktype); | 104 | unsigned int blktype); |
105 | extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); | 105 | extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr, int nonblock); |
106 | 106 | ||
107 | extern int gfs2_inode_refresh(struct gfs2_inode *ip); | 107 | extern int gfs2_inode_refresh(struct gfs2_inode *ip); |
108 | 108 | ||
109 | extern int gfs2_dinode_dealloc(struct gfs2_inode *inode); | ||
110 | extern int gfs2_change_nlink(struct gfs2_inode *ip, int diff); | ||
111 | extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 109 | extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
112 | int is_root); | 110 | int is_root); |
113 | extern struct inode *gfs2_createi(struct gfs2_holder *ghs, | ||
114 | const struct qstr *name, | ||
115 | unsigned int mode, dev_t dev); | ||
116 | extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags); | 111 | extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags); |
117 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 112 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
118 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 113 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
119 | extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); | 114 | extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); |
120 | extern void gfs2_dinode_print(const struct gfs2_inode *ip); | ||
121 | 115 | ||
122 | extern const struct inode_operations gfs2_file_iops; | 116 | extern const struct inode_operations gfs2_file_iops; |
123 | extern const struct inode_operations gfs2_dir_iops; | 117 | extern const struct inode_operations gfs2_dir_iops; |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 5b102c1887fd..cec26c00b50d 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/kthread.h> | 18 | #include <linux/kthread.h> |
19 | #include <linux/freezer.h> | 19 | #include <linux/freezer.h> |
20 | #include <linux/bio.h> | 20 | #include <linux/bio.h> |
21 | #include <linux/writeback.h> | ||
21 | 22 | ||
22 | #include "gfs2.h" | 23 | #include "gfs2.h" |
23 | #include "incore.h" | 24 | #include "incore.h" |
@@ -83,55 +84,97 @@ void gfs2_remove_from_ail(struct gfs2_bufdata *bd) | |||
83 | /** | 84 | /** |
84 | * gfs2_ail1_start_one - Start I/O on a part of the AIL | 85 | * gfs2_ail1_start_one - Start I/O on a part of the AIL |
85 | * @sdp: the filesystem | 86 | * @sdp: the filesystem |
86 | * @tr: the part of the AIL | 87 | * @wbc: The writeback control structure |
88 | * @ai: The ail structure | ||
87 | * | 89 | * |
88 | */ | 90 | */ |
89 | 91 | ||
90 | static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 92 | static int gfs2_ail1_start_one(struct gfs2_sbd *sdp, |
93 | struct writeback_control *wbc, | ||
94 | struct gfs2_ail *ai) | ||
91 | __releases(&sdp->sd_ail_lock) | 95 | __releases(&sdp->sd_ail_lock) |
92 | __acquires(&sdp->sd_ail_lock) | 96 | __acquires(&sdp->sd_ail_lock) |
93 | { | 97 | { |
98 | struct gfs2_glock *gl = NULL; | ||
99 | struct address_space *mapping; | ||
94 | struct gfs2_bufdata *bd, *s; | 100 | struct gfs2_bufdata *bd, *s; |
95 | struct buffer_head *bh; | 101 | struct buffer_head *bh; |
96 | int retry; | ||
97 | 102 | ||
98 | do { | 103 | list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list, bd_ail_st_list) { |
99 | retry = 0; | 104 | bh = bd->bd_bh; |
100 | 105 | ||
101 | list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list, | 106 | gfs2_assert(sdp, bd->bd_ail == ai); |
102 | bd_ail_st_list) { | ||
103 | bh = bd->bd_bh; | ||
104 | 107 | ||
105 | gfs2_assert(sdp, bd->bd_ail == ai); | 108 | if (!buffer_busy(bh)) { |
109 | if (!buffer_uptodate(bh)) | ||
110 | gfs2_io_error_bh(sdp, bh); | ||
111 | list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); | ||
112 | continue; | ||
113 | } | ||
106 | 114 | ||
107 | if (!buffer_busy(bh)) { | 115 | if (!buffer_dirty(bh)) |
108 | if (!buffer_uptodate(bh)) | 116 | continue; |
109 | gfs2_io_error_bh(sdp, bh); | 117 | if (gl == bd->bd_gl) |
110 | list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); | 118 | continue; |
111 | continue; | 119 | gl = bd->bd_gl; |
112 | } | 120 | list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list); |
121 | mapping = bh->b_page->mapping; | ||
122 | if (!mapping) | ||
123 | continue; | ||
124 | spin_unlock(&sdp->sd_ail_lock); | ||
125 | generic_writepages(mapping, wbc); | ||
126 | spin_lock(&sdp->sd_ail_lock); | ||
127 | if (wbc->nr_to_write <= 0) | ||
128 | break; | ||
129 | return 1; | ||
130 | } | ||
113 | 131 | ||
114 | if (!buffer_dirty(bh)) | 132 | return 0; |
115 | continue; | 133 | } |
116 | 134 | ||
117 | list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list); | ||
118 | 135 | ||
119 | get_bh(bh); | 136 | /** |
120 | spin_unlock(&sdp->sd_ail_lock); | 137 | * gfs2_ail1_flush - start writeback of some ail1 entries |
121 | lock_buffer(bh); | 138 | * @sdp: The super block |
122 | if (test_clear_buffer_dirty(bh)) { | 139 | * @wbc: The writeback control structure |
123 | bh->b_end_io = end_buffer_write_sync; | 140 | * |
124 | submit_bh(WRITE_SYNC, bh); | 141 | * Writes back some ail1 entries, according to the limits in the |
125 | } else { | 142 | * writeback control structure |
126 | unlock_buffer(bh); | 143 | */ |
127 | brelse(bh); | 144 | |
128 | } | 145 | void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc) |
129 | spin_lock(&sdp->sd_ail_lock); | 146 | { |
130 | 147 | struct list_head *head = &sdp->sd_ail1_list; | |
131 | retry = 1; | 148 | struct gfs2_ail *ai; |
149 | |||
150 | trace_gfs2_ail_flush(sdp, wbc, 1); | ||
151 | spin_lock(&sdp->sd_ail_lock); | ||
152 | restart: | ||
153 | list_for_each_entry_reverse(ai, head, ai_list) { | ||
154 | if (wbc->nr_to_write <= 0) | ||
132 | break; | 155 | break; |
133 | } | 156 | if (gfs2_ail1_start_one(sdp, wbc, ai)) |
134 | } while (retry); | 157 | goto restart; |
158 | } | ||
159 | spin_unlock(&sdp->sd_ail_lock); | ||
160 | trace_gfs2_ail_flush(sdp, wbc, 0); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * gfs2_ail1_start - start writeback of all ail1 entries | ||
165 | * @sdp: The superblock | ||
166 | */ | ||
167 | |||
168 | static void gfs2_ail1_start(struct gfs2_sbd *sdp) | ||
169 | { | ||
170 | struct writeback_control wbc = { | ||
171 | .sync_mode = WB_SYNC_NONE, | ||
172 | .nr_to_write = LONG_MAX, | ||
173 | .range_start = 0, | ||
174 | .range_end = LLONG_MAX, | ||
175 | }; | ||
176 | |||
177 | return gfs2_ail1_flush(sdp, &wbc); | ||
135 | } | 178 | } |
136 | 179 | ||
137 | /** | 180 | /** |
@@ -141,7 +184,7 @@ __acquires(&sdp->sd_ail_lock) | |||
141 | * | 184 | * |
142 | */ | 185 | */ |
143 | 186 | ||
144 | static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int flags) | 187 | static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) |
145 | { | 188 | { |
146 | struct gfs2_bufdata *bd, *s; | 189 | struct gfs2_bufdata *bd, *s; |
147 | struct buffer_head *bh; | 190 | struct buffer_head *bh; |
@@ -149,71 +192,37 @@ static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int fl | |||
149 | list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list, | 192 | list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list, |
150 | bd_ail_st_list) { | 193 | bd_ail_st_list) { |
151 | bh = bd->bd_bh; | 194 | bh = bd->bd_bh; |
152 | |||
153 | gfs2_assert(sdp, bd->bd_ail == ai); | 195 | gfs2_assert(sdp, bd->bd_ail == ai); |
154 | 196 | if (buffer_busy(bh)) | |
155 | if (buffer_busy(bh)) { | 197 | continue; |
156 | if (flags & DIO_ALL) | ||
157 | continue; | ||
158 | else | ||
159 | break; | ||
160 | } | ||
161 | |||
162 | if (!buffer_uptodate(bh)) | 198 | if (!buffer_uptodate(bh)) |
163 | gfs2_io_error_bh(sdp, bh); | 199 | gfs2_io_error_bh(sdp, bh); |
164 | |||
165 | list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); | 200 | list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list); |
166 | } | 201 | } |
167 | 202 | ||
168 | return list_empty(&ai->ai_ail1_list); | ||
169 | } | 203 | } |
170 | 204 | ||
171 | static void gfs2_ail1_start(struct gfs2_sbd *sdp) | 205 | /** |
172 | { | 206 | * gfs2_ail1_empty - Try to empty the ail1 lists |
173 | struct list_head *head; | 207 | * @sdp: The superblock |
174 | u64 sync_gen; | 208 | * |
175 | struct gfs2_ail *ai; | 209 | * Tries to empty the ail1 lists, starting with the oldest first |
176 | int done = 0; | 210 | */ |
177 | |||
178 | spin_lock(&sdp->sd_ail_lock); | ||
179 | head = &sdp->sd_ail1_list; | ||
180 | if (list_empty(head)) { | ||
181 | spin_unlock(&sdp->sd_ail_lock); | ||
182 | return; | ||
183 | } | ||
184 | sync_gen = sdp->sd_ail_sync_gen++; | ||
185 | |||
186 | while(!done) { | ||
187 | done = 1; | ||
188 | list_for_each_entry_reverse(ai, head, ai_list) { | ||
189 | if (ai->ai_sync_gen >= sync_gen) | ||
190 | continue; | ||
191 | ai->ai_sync_gen = sync_gen; | ||
192 | gfs2_ail1_start_one(sdp, ai); /* This may drop ail lock */ | ||
193 | done = 0; | ||
194 | break; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | spin_unlock(&sdp->sd_ail_lock); | ||
199 | } | ||
200 | 211 | ||
201 | static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) | 212 | static int gfs2_ail1_empty(struct gfs2_sbd *sdp) |
202 | { | 213 | { |
203 | struct gfs2_ail *ai, *s; | 214 | struct gfs2_ail *ai, *s; |
204 | int ret; | 215 | int ret; |
205 | 216 | ||
206 | spin_lock(&sdp->sd_ail_lock); | 217 | spin_lock(&sdp->sd_ail_lock); |
207 | |||
208 | list_for_each_entry_safe_reverse(ai, s, &sdp->sd_ail1_list, ai_list) { | 218 | list_for_each_entry_safe_reverse(ai, s, &sdp->sd_ail1_list, ai_list) { |
209 | if (gfs2_ail1_empty_one(sdp, ai, flags)) | 219 | gfs2_ail1_empty_one(sdp, ai); |
220 | if (list_empty(&ai->ai_ail1_list)) | ||
210 | list_move(&ai->ai_list, &sdp->sd_ail2_list); | 221 | list_move(&ai->ai_list, &sdp->sd_ail2_list); |
211 | else if (!(flags & DIO_ALL)) | 222 | else |
212 | break; | 223 | break; |
213 | } | 224 | } |
214 | |||
215 | ret = list_empty(&sdp->sd_ail1_list); | 225 | ret = list_empty(&sdp->sd_ail1_list); |
216 | |||
217 | spin_unlock(&sdp->sd_ail_lock); | 226 | spin_unlock(&sdp->sd_ail_lock); |
218 | 227 | ||
219 | return ret; | 228 | return ret; |
@@ -574,7 +583,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) | |||
574 | set_buffer_uptodate(bh); | 583 | set_buffer_uptodate(bh); |
575 | clear_buffer_dirty(bh); | 584 | clear_buffer_dirty(bh); |
576 | 585 | ||
577 | gfs2_ail1_empty(sdp, 0); | 586 | gfs2_ail1_empty(sdp); |
578 | tail = current_tail(sdp); | 587 | tail = current_tail(sdp); |
579 | 588 | ||
580 | lh = (struct gfs2_log_header *)bh->b_data; | 589 | lh = (struct gfs2_log_header *)bh->b_data; |
@@ -869,7 +878,7 @@ void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | |||
869 | gfs2_log_flush(sdp, NULL); | 878 | gfs2_log_flush(sdp, NULL); |
870 | for (;;) { | 879 | for (;;) { |
871 | gfs2_ail1_start(sdp); | 880 | gfs2_ail1_start(sdp); |
872 | if (gfs2_ail1_empty(sdp, DIO_ALL)) | 881 | if (gfs2_ail1_empty(sdp)) |
873 | break; | 882 | break; |
874 | msleep(10); | 883 | msleep(10); |
875 | } | 884 | } |
@@ -905,17 +914,15 @@ int gfs2_logd(void *data) | |||
905 | 914 | ||
906 | preflush = atomic_read(&sdp->sd_log_pinned); | 915 | preflush = atomic_read(&sdp->sd_log_pinned); |
907 | if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { | 916 | if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { |
908 | gfs2_ail1_empty(sdp, DIO_ALL); | 917 | gfs2_ail1_empty(sdp); |
909 | gfs2_log_flush(sdp, NULL); | 918 | gfs2_log_flush(sdp, NULL); |
910 | gfs2_ail1_empty(sdp, DIO_ALL); | ||
911 | } | 919 | } |
912 | 920 | ||
913 | if (gfs2_ail_flush_reqd(sdp)) { | 921 | if (gfs2_ail_flush_reqd(sdp)) { |
914 | gfs2_ail1_start(sdp); | 922 | gfs2_ail1_start(sdp); |
915 | io_schedule(); | 923 | io_schedule(); |
916 | gfs2_ail1_empty(sdp, 0); | 924 | gfs2_ail1_empty(sdp); |
917 | gfs2_log_flush(sdp, NULL); | 925 | gfs2_log_flush(sdp, NULL); |
918 | gfs2_ail1_empty(sdp, DIO_ALL); | ||
919 | } | 926 | } |
920 | 927 | ||
921 | wake_up(&sdp->sd_log_waitq); | 928 | wake_up(&sdp->sd_log_waitq); |
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index 0d007f920234..ab0621698b73 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/list.h> | 13 | #include <linux/list.h> |
14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
15 | #include <linux/writeback.h> | ||
15 | #include "incore.h" | 16 | #include "incore.h" |
16 | 17 | ||
17 | /** | 18 | /** |
@@ -59,6 +60,7 @@ extern struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, | |||
59 | extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); | 60 | extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); |
60 | extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); | 61 | extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); |
61 | extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd); | 62 | extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd); |
63 | extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc); | ||
62 | 64 | ||
63 | extern void gfs2_log_shutdown(struct gfs2_sbd *sdp); | 65 | extern void gfs2_log_shutdown(struct gfs2_sbd *sdp); |
64 | extern void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | 66 | extern void gfs2_meta_syncfs(struct gfs2_sbd *sdp); |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 51d27f00ebb4..05bbb124699f 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -40,7 +40,7 @@ static void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh) | |||
40 | { | 40 | { |
41 | struct gfs2_bufdata *bd; | 41 | struct gfs2_bufdata *bd; |
42 | 42 | ||
43 | gfs2_assert_withdraw(sdp, test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)); | 43 | BUG_ON(!current->journal_info); |
44 | 44 | ||
45 | clear_buffer_dirty(bh); | 45 | clear_buffer_dirty(bh); |
46 | if (test_set_buffer_pinned(bh)) | 46 | if (test_set_buffer_pinned(bh)) |
@@ -65,6 +65,7 @@ static void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh) | |||
65 | * @sdp: the filesystem the buffer belongs to | 65 | * @sdp: the filesystem the buffer belongs to |
66 | * @bh: The buffer to unpin | 66 | * @bh: The buffer to unpin |
67 | * @ai: | 67 | * @ai: |
68 | * @flags: The inode dirty flags | ||
68 | * | 69 | * |
69 | */ | 70 | */ |
70 | 71 | ||
@@ -73,10 +74,8 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
73 | { | 74 | { |
74 | struct gfs2_bufdata *bd = bh->b_private; | 75 | struct gfs2_bufdata *bd = bh->b_private; |
75 | 76 | ||
76 | gfs2_assert_withdraw(sdp, buffer_uptodate(bh)); | 77 | BUG_ON(!buffer_uptodate(bh)); |
77 | 78 | BUG_ON(!buffer_pinned(bh)); | |
78 | if (!buffer_pinned(bh)) | ||
79 | gfs2_assert_withdraw(sdp, 0); | ||
80 | 79 | ||
81 | lock_buffer(bh); | 80 | lock_buffer(bh); |
82 | mark_buffer_dirty(bh); | 81 | mark_buffer_dirty(bh); |
@@ -95,8 +94,7 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
95 | list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list); | 94 | list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list); |
96 | spin_unlock(&sdp->sd_ail_lock); | 95 | spin_unlock(&sdp->sd_ail_lock); |
97 | 96 | ||
98 | if (test_and_clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags)) | 97 | clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); |
99 | gfs2_glock_schedule_for_reclaim(bd->bd_gl); | ||
100 | trace_gfs2_pin(bd, 0); | 98 | trace_gfs2_pin(bd, 0); |
101 | unlock_buffer(bh); | 99 | unlock_buffer(bh); |
102 | atomic_dec(&sdp->sd_log_pinned); | 100 | atomic_dec(&sdp->sd_log_pinned); |
@@ -322,12 +320,16 @@ static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass) | |||
322 | 320 | ||
323 | static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) | 321 | static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) |
324 | { | 322 | { |
323 | struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le); | ||
324 | struct gfs2_glock *gl = bd->bd_gl; | ||
325 | struct gfs2_trans *tr; | 325 | struct gfs2_trans *tr; |
326 | 326 | ||
327 | tr = current->journal_info; | 327 | tr = current->journal_info; |
328 | tr->tr_touched = 1; | 328 | tr->tr_touched = 1; |
329 | tr->tr_num_revoke++; | 329 | tr->tr_num_revoke++; |
330 | sdp->sd_log_num_revoke++; | 330 | sdp->sd_log_num_revoke++; |
331 | atomic_inc(&gl->gl_revokes); | ||
332 | set_bit(GLF_LFLUSH, &gl->gl_flags); | ||
331 | list_add(&le->le_list, &sdp->sd_log_le_revoke); | 333 | list_add(&le->le_list, &sdp->sd_log_le_revoke); |
332 | } | 334 | } |
333 | 335 | ||
@@ -350,9 +352,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | |||
350 | ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke); | 352 | ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke); |
351 | offset = sizeof(struct gfs2_log_descriptor); | 353 | offset = sizeof(struct gfs2_log_descriptor); |
352 | 354 | ||
353 | while (!list_empty(head)) { | 355 | list_for_each_entry(bd, head, bd_le.le_list) { |
354 | bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); | ||
355 | list_del_init(&bd->bd_le.le_list); | ||
356 | sdp->sd_log_num_revoke--; | 356 | sdp->sd_log_num_revoke--; |
357 | 357 | ||
358 | if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { | 358 | if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { |
@@ -367,8 +367,6 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | |||
367 | } | 367 | } |
368 | 368 | ||
369 | *(__be64 *)(bh->b_data + offset) = cpu_to_be64(bd->bd_blkno); | 369 | *(__be64 *)(bh->b_data + offset) = cpu_to_be64(bd->bd_blkno); |
370 | kmem_cache_free(gfs2_bufdata_cachep, bd); | ||
371 | |||
372 | offset += sizeof(u64); | 370 | offset += sizeof(u64); |
373 | } | 371 | } |
374 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); | 372 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); |
@@ -376,6 +374,22 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | |||
376 | submit_bh(WRITE_SYNC, bh); | 374 | submit_bh(WRITE_SYNC, bh); |
377 | } | 375 | } |
378 | 376 | ||
377 | static void revoke_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | ||
378 | { | ||
379 | struct list_head *head = &sdp->sd_log_le_revoke; | ||
380 | struct gfs2_bufdata *bd; | ||
381 | struct gfs2_glock *gl; | ||
382 | |||
383 | while (!list_empty(head)) { | ||
384 | bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); | ||
385 | list_del_init(&bd->bd_le.le_list); | ||
386 | gl = bd->bd_gl; | ||
387 | atomic_dec(&gl->gl_revokes); | ||
388 | clear_bit(GLF_LFLUSH, &gl->gl_flags); | ||
389 | kmem_cache_free(gfs2_bufdata_cachep, bd); | ||
390 | } | ||
391 | } | ||
392 | |||
379 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, | 393 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, |
380 | struct gfs2_log_header_host *head, int pass) | 394 | struct gfs2_log_header_host *head, int pass) |
381 | { | 395 | { |
@@ -749,6 +763,7 @@ const struct gfs2_log_operations gfs2_buf_lops = { | |||
749 | const struct gfs2_log_operations gfs2_revoke_lops = { | 763 | const struct gfs2_log_operations gfs2_revoke_lops = { |
750 | .lo_add = revoke_lo_add, | 764 | .lo_add = revoke_lo_add, |
751 | .lo_before_commit = revoke_lo_before_commit, | 765 | .lo_before_commit = revoke_lo_before_commit, |
766 | .lo_after_commit = revoke_lo_after_commit, | ||
752 | .lo_before_scan = revoke_lo_before_scan, | 767 | .lo_before_scan = revoke_lo_before_scan, |
753 | .lo_scan_elements = revoke_lo_scan_elements, | 768 | .lo_scan_elements = revoke_lo_scan_elements, |
754 | .lo_after_scan = revoke_lo_after_scan, | 769 | .lo_after_scan = revoke_lo_after_scan, |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 888a5f5a1a58..cfa327d33194 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -53,6 +53,7 @@ static void gfs2_init_glock_once(void *foo) | |||
53 | INIT_LIST_HEAD(&gl->gl_lru); | 53 | INIT_LIST_HEAD(&gl->gl_lru); |
54 | INIT_LIST_HEAD(&gl->gl_ail_list); | 54 | INIT_LIST_HEAD(&gl->gl_ail_list); |
55 | atomic_set(&gl->gl_ail_count, 0); | 55 | atomic_set(&gl->gl_ail_count, 0); |
56 | atomic_set(&gl->gl_revokes, 0); | ||
56 | } | 57 | } |
57 | 58 | ||
58 | static void gfs2_init_gl_aspace_once(void *foo) | 59 | static void gfs2_init_gl_aspace_once(void *foo) |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 675349b5a133..747238cd9f96 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "rgrp.h" | 31 | #include "rgrp.h" |
32 | #include "trans.h" | 32 | #include "trans.h" |
33 | #include "util.h" | 33 | #include "util.h" |
34 | #include "trace_gfs2.h" | ||
34 | 35 | ||
35 | static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wbc) | 36 | static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wbc) |
36 | { | 37 | { |
@@ -310,6 +311,7 @@ void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int | |||
310 | struct gfs2_bufdata *bd = bh->b_private; | 311 | struct gfs2_bufdata *bd = bh->b_private; |
311 | 312 | ||
312 | if (test_clear_buffer_pinned(bh)) { | 313 | if (test_clear_buffer_pinned(bh)) { |
314 | trace_gfs2_pin(bd, 0); | ||
313 | atomic_dec(&sdp->sd_log_pinned); | 315 | atomic_dec(&sdp->sd_log_pinned); |
314 | list_del_init(&bd->bd_le.le_list); | 316 | list_del_init(&bd->bd_le.le_list); |
315 | if (meta) { | 317 | if (meta) { |
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h index 6a1d9ba16411..22c526593131 100644 --- a/fs/gfs2/meta_io.h +++ b/fs/gfs2/meta_io.h | |||
@@ -77,8 +77,6 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); | |||
77 | 77 | ||
78 | #define buffer_busy(bh) \ | 78 | #define buffer_busy(bh) \ |
79 | ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned))) | 79 | ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned))) |
80 | #define buffer_in_io(bh) \ | ||
81 | ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock))) | ||
82 | 80 | ||
83 | #endif /* __DIO_DOT_H__ */ | 81 | #endif /* __DIO_DOT_H__ */ |
84 | 82 | ||
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index d3c69eb91c74..8ac9ae189b53 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -126,8 +126,10 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
126 | * changed. | 126 | * changed. |
127 | */ | 127 | */ |
128 | 128 | ||
129 | static int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) | 129 | static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent) |
130 | { | 130 | { |
131 | struct gfs2_sb_host *sb = &sdp->sd_sb; | ||
132 | |||
131 | if (sb->sb_magic != GFS2_MAGIC || | 133 | if (sb->sb_magic != GFS2_MAGIC || |
132 | sb->sb_type != GFS2_METATYPE_SB) { | 134 | sb->sb_type != GFS2_METATYPE_SB) { |
133 | if (!silent) | 135 | if (!silent) |
@@ -157,8 +159,10 @@ static void end_bio_io_page(struct bio *bio, int error) | |||
157 | unlock_page(page); | 159 | unlock_page(page); |
158 | } | 160 | } |
159 | 161 | ||
160 | static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) | 162 | static void gfs2_sb_in(struct gfs2_sbd *sdp, const void *buf) |
161 | { | 163 | { |
164 | struct gfs2_sb_host *sb = &sdp->sd_sb; | ||
165 | struct super_block *s = sdp->sd_vfs; | ||
162 | const struct gfs2_sb *str = buf; | 166 | const struct gfs2_sb *str = buf; |
163 | 167 | ||
164 | sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); | 168 | sb->sb_magic = be32_to_cpu(str->sb_header.mh_magic); |
@@ -175,7 +179,7 @@ static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) | |||
175 | 179 | ||
176 | memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); | 180 | memcpy(sb->sb_lockproto, str->sb_lockproto, GFS2_LOCKNAME_LEN); |
177 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); | 181 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); |
178 | memcpy(sb->sb_uuid, str->sb_uuid, 16); | 182 | memcpy(s->s_uuid, str->sb_uuid, 16); |
179 | } | 183 | } |
180 | 184 | ||
181 | /** | 185 | /** |
@@ -197,7 +201,7 @@ static void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) | |||
197 | * Returns: 0 on success or error | 201 | * Returns: 0 on success or error |
198 | */ | 202 | */ |
199 | 203 | ||
200 | static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) | 204 | static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector, int silent) |
201 | { | 205 | { |
202 | struct super_block *sb = sdp->sd_vfs; | 206 | struct super_block *sb = sdp->sd_vfs; |
203 | struct gfs2_sb *p; | 207 | struct gfs2_sb *p; |
@@ -227,10 +231,10 @@ static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector) | |||
227 | return -EIO; | 231 | return -EIO; |
228 | } | 232 | } |
229 | p = kmap(page); | 233 | p = kmap(page); |
230 | gfs2_sb_in(&sdp->sd_sb, p); | 234 | gfs2_sb_in(sdp, p); |
231 | kunmap(page); | 235 | kunmap(page); |
232 | __free_page(page); | 236 | __free_page(page); |
233 | return 0; | 237 | return gfs2_check_sb(sdp, silent); |
234 | } | 238 | } |
235 | 239 | ||
236 | /** | 240 | /** |
@@ -247,17 +251,13 @@ static int gfs2_read_sb(struct gfs2_sbd *sdp, int silent) | |||
247 | unsigned int x; | 251 | unsigned int x; |
248 | int error; | 252 | int error; |
249 | 253 | ||
250 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); | 254 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift, silent); |
251 | if (error) { | 255 | if (error) { |
252 | if (!silent) | 256 | if (!silent) |
253 | fs_err(sdp, "can't read superblock\n"); | 257 | fs_err(sdp, "can't read superblock\n"); |
254 | return error; | 258 | return error; |
255 | } | 259 | } |
256 | 260 | ||
257 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); | ||
258 | if (error) | ||
259 | return error; | ||
260 | |||
261 | sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - | 261 | sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - |
262 | GFS2_BASIC_BLOCK_SHIFT; | 262 | GFS2_BASIC_BLOCK_SHIFT; |
263 | sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; | 263 | sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; |
@@ -340,14 +340,10 @@ static int init_names(struct gfs2_sbd *sdp, int silent) | |||
340 | /* Try to autodetect */ | 340 | /* Try to autodetect */ |
341 | 341 | ||
342 | if (!proto[0] || !table[0]) { | 342 | if (!proto[0] || !table[0]) { |
343 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift); | 343 | error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift, silent); |
344 | if (error) | 344 | if (error) |
345 | return error; | 345 | return error; |
346 | 346 | ||
347 | error = gfs2_check_sb(sdp, &sdp->sd_sb, silent); | ||
348 | if (error) | ||
349 | goto out; | ||
350 | |||
351 | if (!proto[0]) | 347 | if (!proto[0]) |
352 | proto = sdp->sd_sb.sb_lockproto; | 348 | proto = sdp->sd_sb.sb_lockproto; |
353 | if (!table[0]) | 349 | if (!table[0]) |
@@ -364,7 +360,6 @@ static int init_names(struct gfs2_sbd *sdp, int silent) | |||
364 | while ((table = strchr(table, '/'))) | 360 | while ((table = strchr(table, '/'))) |
365 | *table = '_'; | 361 | *table = '_'; |
366 | 362 | ||
367 | out: | ||
368 | return error; | 363 | return error; |
369 | } | 364 | } |
370 | 365 | ||
@@ -1119,8 +1114,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent | |||
1119 | if (sdp->sd_args.ar_statfs_quantum) { | 1114 | if (sdp->sd_args.ar_statfs_quantum) { |
1120 | sdp->sd_tune.gt_statfs_slow = 0; | 1115 | sdp->sd_tune.gt_statfs_slow = 0; |
1121 | sdp->sd_tune.gt_statfs_quantum = sdp->sd_args.ar_statfs_quantum; | 1116 | sdp->sd_tune.gt_statfs_quantum = sdp->sd_args.ar_statfs_quantum; |
1122 | } | 1117 | } else { |
1123 | else { | ||
1124 | sdp->sd_tune.gt_statfs_slow = 1; | 1118 | sdp->sd_tune.gt_statfs_slow = 1; |
1125 | sdp->sd_tune.gt_statfs_quantum = 30; | 1119 | sdp->sd_tune.gt_statfs_quantum = 30; |
1126 | } | 1120 | } |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c deleted file mode 100644 index 09e436a50723..000000000000 --- a/fs/gfs2/ops_inode.c +++ /dev/null | |||
@@ -1,1344 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/slab.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/completion.h> | ||
13 | #include <linux/buffer_head.h> | ||
14 | #include <linux/namei.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/xattr.h> | ||
17 | #include <linux/posix_acl.h> | ||
18 | #include <linux/gfs2_ondisk.h> | ||
19 | #include <linux/crc32.h> | ||
20 | #include <linux/fiemap.h> | ||
21 | #include <asm/uaccess.h> | ||
22 | |||
23 | #include "gfs2.h" | ||
24 | #include "incore.h" | ||
25 | #include "acl.h" | ||
26 | #include "bmap.h" | ||
27 | #include "dir.h" | ||
28 | #include "xattr.h" | ||
29 | #include "glock.h" | ||
30 | #include "inode.h" | ||
31 | #include "meta_io.h" | ||
32 | #include "quota.h" | ||
33 | #include "rgrp.h" | ||
34 | #include "trans.h" | ||
35 | #include "util.h" | ||
36 | #include "super.h" | ||
37 | |||
38 | /** | ||
39 | * gfs2_create - Create a file | ||
40 | * @dir: The directory in which to create the file | ||
41 | * @dentry: The dentry of the new file | ||
42 | * @mode: The mode of the new file | ||
43 | * | ||
44 | * Returns: errno | ||
45 | */ | ||
46 | |||
47 | static int gfs2_create(struct inode *dir, struct dentry *dentry, | ||
48 | int mode, struct nameidata *nd) | ||
49 | { | ||
50 | struct gfs2_inode *dip = GFS2_I(dir); | ||
51 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
52 | struct gfs2_holder ghs[2]; | ||
53 | struct inode *inode; | ||
54 | |||
55 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | ||
56 | |||
57 | for (;;) { | ||
58 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0); | ||
59 | if (!IS_ERR(inode)) { | ||
60 | gfs2_trans_end(sdp); | ||
61 | if (dip->i_alloc->al_rgd) | ||
62 | gfs2_inplace_release(dip); | ||
63 | gfs2_quota_unlock(dip); | ||
64 | gfs2_alloc_put(dip); | ||
65 | gfs2_glock_dq_uninit_m(2, ghs); | ||
66 | mark_inode_dirty(inode); | ||
67 | break; | ||
68 | } else if (PTR_ERR(inode) != -EEXIST || | ||
69 | (nd && nd->flags & LOOKUP_EXCL)) { | ||
70 | gfs2_holder_uninit(ghs); | ||
71 | return PTR_ERR(inode); | ||
72 | } | ||
73 | |||
74 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); | ||
75 | if (inode) { | ||
76 | if (!IS_ERR(inode)) { | ||
77 | gfs2_holder_uninit(ghs); | ||
78 | break; | ||
79 | } else { | ||
80 | gfs2_holder_uninit(ghs); | ||
81 | return PTR_ERR(inode); | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | d_instantiate(dentry, inode); | ||
87 | |||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * gfs2_lookup - Look up a filename in a directory and return its inode | ||
93 | * @dir: The directory inode | ||
94 | * @dentry: The dentry of the new inode | ||
95 | * @nd: passed from Linux VFS, ignored by us | ||
96 | * | ||
97 | * Called by the VFS layer. Lock dir and call gfs2_lookupi() | ||
98 | * | ||
99 | * Returns: errno | ||
100 | */ | ||
101 | |||
102 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, | ||
103 | struct nameidata *nd) | ||
104 | { | ||
105 | struct inode *inode = NULL; | ||
106 | |||
107 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); | ||
108 | if (inode && IS_ERR(inode)) | ||
109 | return ERR_CAST(inode); | ||
110 | |||
111 | if (inode) { | ||
112 | struct gfs2_glock *gl = GFS2_I(inode)->i_gl; | ||
113 | struct gfs2_holder gh; | ||
114 | int error; | ||
115 | error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | ||
116 | if (error) { | ||
117 | iput(inode); | ||
118 | return ERR_PTR(error); | ||
119 | } | ||
120 | gfs2_glock_dq_uninit(&gh); | ||
121 | return d_splice_alias(inode, dentry); | ||
122 | } | ||
123 | d_add(dentry, inode); | ||
124 | |||
125 | return NULL; | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * gfs2_link - Link to a file | ||
130 | * @old_dentry: The inode to link | ||
131 | * @dir: Add link to this directory | ||
132 | * @dentry: The name of the link | ||
133 | * | ||
134 | * Link the inode in "old_dentry" into the directory "dir" with the | ||
135 | * name in "dentry". | ||
136 | * | ||
137 | * Returns: errno | ||
138 | */ | ||
139 | |||
140 | static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | ||
141 | struct dentry *dentry) | ||
142 | { | ||
143 | struct gfs2_inode *dip = GFS2_I(dir); | ||
144 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
145 | struct inode *inode = old_dentry->d_inode; | ||
146 | struct gfs2_inode *ip = GFS2_I(inode); | ||
147 | struct gfs2_holder ghs[2]; | ||
148 | int alloc_required; | ||
149 | int error; | ||
150 | |||
151 | if (S_ISDIR(inode->i_mode)) | ||
152 | return -EPERM; | ||
153 | |||
154 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | ||
155 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | ||
156 | |||
157 | error = gfs2_glock_nq(ghs); /* parent */ | ||
158 | if (error) | ||
159 | goto out_parent; | ||
160 | |||
161 | error = gfs2_glock_nq(ghs + 1); /* child */ | ||
162 | if (error) | ||
163 | goto out_child; | ||
164 | |||
165 | error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC, 0); | ||
166 | if (error) | ||
167 | goto out_gunlock; | ||
168 | |||
169 | error = gfs2_dir_check(dir, &dentry->d_name, NULL); | ||
170 | switch (error) { | ||
171 | case -ENOENT: | ||
172 | break; | ||
173 | case 0: | ||
174 | error = -EEXIST; | ||
175 | default: | ||
176 | goto out_gunlock; | ||
177 | } | ||
178 | |||
179 | error = -EINVAL; | ||
180 | if (!dip->i_inode.i_nlink) | ||
181 | goto out_gunlock; | ||
182 | error = -EFBIG; | ||
183 | if (dip->i_entries == (u32)-1) | ||
184 | goto out_gunlock; | ||
185 | error = -EPERM; | ||
186 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | ||
187 | goto out_gunlock; | ||
188 | error = -EINVAL; | ||
189 | if (!ip->i_inode.i_nlink) | ||
190 | goto out_gunlock; | ||
191 | error = -EMLINK; | ||
192 | if (ip->i_inode.i_nlink == (u32)-1) | ||
193 | goto out_gunlock; | ||
194 | |||
195 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); | ||
196 | if (error < 0) | ||
197 | goto out_gunlock; | ||
198 | error = 0; | ||
199 | |||
200 | if (alloc_required) { | ||
201 | struct gfs2_alloc *al = gfs2_alloc_get(dip); | ||
202 | if (!al) { | ||
203 | error = -ENOMEM; | ||
204 | goto out_gunlock; | ||
205 | } | ||
206 | |||
207 | error = gfs2_quota_lock_check(dip); | ||
208 | if (error) | ||
209 | goto out_alloc; | ||
210 | |||
211 | al->al_requested = sdp->sd_max_dirres; | ||
212 | |||
213 | error = gfs2_inplace_reserve(dip); | ||
214 | if (error) | ||
215 | goto out_gunlock_q; | ||
216 | |||
217 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | ||
218 | gfs2_rg_blocks(al) + | ||
219 | 2 * RES_DINODE + RES_STATFS + | ||
220 | RES_QUOTA, 0); | ||
221 | if (error) | ||
222 | goto out_ipres; | ||
223 | } else { | ||
224 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF, 0); | ||
225 | if (error) | ||
226 | goto out_ipres; | ||
227 | } | ||
228 | |||
229 | error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode)); | ||
230 | if (error) | ||
231 | goto out_end_trans; | ||
232 | |||
233 | error = gfs2_change_nlink(ip, +1); | ||
234 | |||
235 | out_end_trans: | ||
236 | gfs2_trans_end(sdp); | ||
237 | out_ipres: | ||
238 | if (alloc_required) | ||
239 | gfs2_inplace_release(dip); | ||
240 | out_gunlock_q: | ||
241 | if (alloc_required) | ||
242 | gfs2_quota_unlock(dip); | ||
243 | out_alloc: | ||
244 | if (alloc_required) | ||
245 | gfs2_alloc_put(dip); | ||
246 | out_gunlock: | ||
247 | gfs2_glock_dq(ghs + 1); | ||
248 | out_child: | ||
249 | gfs2_glock_dq(ghs); | ||
250 | out_parent: | ||
251 | gfs2_holder_uninit(ghs); | ||
252 | gfs2_holder_uninit(ghs + 1); | ||
253 | if (!error) { | ||
254 | ihold(inode); | ||
255 | d_instantiate(dentry, inode); | ||
256 | mark_inode_dirty(inode); | ||
257 | } | ||
258 | return error; | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * gfs2_unlink_ok - check to see that a inode is still in a directory | ||
263 | * @dip: the directory | ||
264 | * @name: the name of the file | ||
265 | * @ip: the inode | ||
266 | * | ||
267 | * Assumes that the lock on (at least) @dip is held. | ||
268 | * | ||
269 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | ||
270 | */ | ||
271 | |||
272 | static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
273 | const struct gfs2_inode *ip) | ||
274 | { | ||
275 | int error; | ||
276 | |||
277 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | ||
278 | return -EPERM; | ||
279 | |||
280 | if ((dip->i_inode.i_mode & S_ISVTX) && | ||
281 | dip->i_inode.i_uid != current_fsuid() && | ||
282 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | ||
283 | return -EPERM; | ||
284 | |||
285 | if (IS_APPEND(&dip->i_inode)) | ||
286 | return -EPERM; | ||
287 | |||
288 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC, 0); | ||
289 | if (error) | ||
290 | return error; | ||
291 | |||
292 | error = gfs2_dir_check(&dip->i_inode, name, ip); | ||
293 | if (error) | ||
294 | return error; | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * gfs2_unlink - Unlink a file | ||
301 | * @dir: The inode of the directory containing the file to unlink | ||
302 | * @dentry: The file itself | ||
303 | * | ||
304 | * Unlink a file. Call gfs2_unlinki() | ||
305 | * | ||
306 | * Returns: errno | ||
307 | */ | ||
308 | |||
309 | static int gfs2_unlink(struct inode *dir, struct dentry *dentry) | ||
310 | { | ||
311 | struct gfs2_inode *dip = GFS2_I(dir); | ||
312 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
313 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
314 | struct gfs2_holder ghs[3]; | ||
315 | struct gfs2_rgrpd *rgd; | ||
316 | struct gfs2_holder ri_gh; | ||
317 | int error; | ||
318 | |||
319 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
320 | if (error) | ||
321 | return error; | ||
322 | |||
323 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | ||
324 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | ||
325 | |||
326 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | ||
327 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | ||
328 | |||
329 | |||
330 | error = gfs2_glock_nq(ghs); /* parent */ | ||
331 | if (error) | ||
332 | goto out_parent; | ||
333 | |||
334 | error = gfs2_glock_nq(ghs + 1); /* child */ | ||
335 | if (error) | ||
336 | goto out_child; | ||
337 | |||
338 | error = gfs2_glock_nq(ghs + 2); /* rgrp */ | ||
339 | if (error) | ||
340 | goto out_rgrp; | ||
341 | |||
342 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); | ||
343 | if (error) | ||
344 | goto out_gunlock; | ||
345 | |||
346 | error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0); | ||
347 | if (error) | ||
348 | goto out_gunlock; | ||
349 | |||
350 | error = gfs2_dir_del(dip, &dentry->d_name); | ||
351 | if (error) | ||
352 | goto out_end_trans; | ||
353 | |||
354 | error = gfs2_change_nlink(ip, -1); | ||
355 | |||
356 | out_end_trans: | ||
357 | gfs2_trans_end(sdp); | ||
358 | out_gunlock: | ||
359 | gfs2_glock_dq(ghs + 2); | ||
360 | out_rgrp: | ||
361 | gfs2_holder_uninit(ghs + 2); | ||
362 | gfs2_glock_dq(ghs + 1); | ||
363 | out_child: | ||
364 | gfs2_holder_uninit(ghs + 1); | ||
365 | gfs2_glock_dq(ghs); | ||
366 | out_parent: | ||
367 | gfs2_holder_uninit(ghs); | ||
368 | gfs2_glock_dq_uninit(&ri_gh); | ||
369 | return error; | ||
370 | } | ||
371 | |||
372 | /** | ||
373 | * gfs2_symlink - Create a symlink | ||
374 | * @dir: The directory to create the symlink in | ||
375 | * @dentry: The dentry to put the symlink in | ||
376 | * @symname: The thing which the link points to | ||
377 | * | ||
378 | * Returns: errno | ||
379 | */ | ||
380 | |||
381 | static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | ||
382 | const char *symname) | ||
383 | { | ||
384 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | ||
385 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
386 | struct gfs2_holder ghs[2]; | ||
387 | struct inode *inode; | ||
388 | struct buffer_head *dibh; | ||
389 | int size; | ||
390 | int error; | ||
391 | |||
392 | /* Must be stuffed with a null terminator for gfs2_follow_link() */ | ||
393 | size = strlen(symname); | ||
394 | if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1) | ||
395 | return -ENAMETOOLONG; | ||
396 | |||
397 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | ||
398 | |||
399 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0); | ||
400 | if (IS_ERR(inode)) { | ||
401 | gfs2_holder_uninit(ghs); | ||
402 | return PTR_ERR(inode); | ||
403 | } | ||
404 | |||
405 | ip = ghs[1].gh_gl->gl_object; | ||
406 | |||
407 | i_size_write(inode, size); | ||
408 | |||
409 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
410 | |||
411 | if (!gfs2_assert_withdraw(sdp, !error)) { | ||
412 | gfs2_dinode_out(ip, dibh->b_data); | ||
413 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, | ||
414 | size); | ||
415 | brelse(dibh); | ||
416 | } | ||
417 | |||
418 | gfs2_trans_end(sdp); | ||
419 | if (dip->i_alloc->al_rgd) | ||
420 | gfs2_inplace_release(dip); | ||
421 | gfs2_quota_unlock(dip); | ||
422 | gfs2_alloc_put(dip); | ||
423 | |||
424 | gfs2_glock_dq_uninit_m(2, ghs); | ||
425 | |||
426 | d_instantiate(dentry, inode); | ||
427 | mark_inode_dirty(inode); | ||
428 | |||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | /** | ||
433 | * gfs2_mkdir - Make a directory | ||
434 | * @dir: The parent directory of the new one | ||
435 | * @dentry: The dentry of the new directory | ||
436 | * @mode: The mode of the new directory | ||
437 | * | ||
438 | * Returns: errno | ||
439 | */ | ||
440 | |||
441 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | ||
442 | { | ||
443 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | ||
444 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
445 | struct gfs2_holder ghs[2]; | ||
446 | struct inode *inode; | ||
447 | struct buffer_head *dibh; | ||
448 | int error; | ||
449 | |||
450 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | ||
451 | |||
452 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0); | ||
453 | if (IS_ERR(inode)) { | ||
454 | gfs2_holder_uninit(ghs); | ||
455 | return PTR_ERR(inode); | ||
456 | } | ||
457 | |||
458 | ip = ghs[1].gh_gl->gl_object; | ||
459 | |||
460 | ip->i_inode.i_nlink = 2; | ||
461 | i_size_write(inode, sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)); | ||
462 | ip->i_diskflags |= GFS2_DIF_JDATA; | ||
463 | ip->i_entries = 2; | ||
464 | |||
465 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
466 | |||
467 | if (!gfs2_assert_withdraw(sdp, !error)) { | ||
468 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; | ||
469 | struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); | ||
470 | |||
471 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
472 | gfs2_qstr2dirent(&gfs2_qdot, GFS2_DIRENT_SIZE(gfs2_qdot.len), dent); | ||
473 | dent->de_inum = di->di_num; /* already GFS2 endian */ | ||
474 | dent->de_type = cpu_to_be16(DT_DIR); | ||
475 | di->di_entries = cpu_to_be32(1); | ||
476 | |||
477 | dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); | ||
478 | gfs2_qstr2dirent(&gfs2_qdotdot, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); | ||
479 | |||
480 | gfs2_inum_out(dip, dent); | ||
481 | dent->de_type = cpu_to_be16(DT_DIR); | ||
482 | |||
483 | gfs2_dinode_out(ip, di); | ||
484 | |||
485 | brelse(dibh); | ||
486 | } | ||
487 | |||
488 | error = gfs2_change_nlink(dip, +1); | ||
489 | gfs2_assert_withdraw(sdp, !error); /* dip already pinned */ | ||
490 | |||
491 | gfs2_trans_end(sdp); | ||
492 | if (dip->i_alloc->al_rgd) | ||
493 | gfs2_inplace_release(dip); | ||
494 | gfs2_quota_unlock(dip); | ||
495 | gfs2_alloc_put(dip); | ||
496 | |||
497 | gfs2_glock_dq_uninit_m(2, ghs); | ||
498 | |||
499 | d_instantiate(dentry, inode); | ||
500 | mark_inode_dirty(inode); | ||
501 | |||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | /** | ||
506 | * gfs2_rmdiri - Remove a directory | ||
507 | * @dip: The parent directory of the directory to be removed | ||
508 | * @name: The name of the directory to be removed | ||
509 | * @ip: The GFS2 inode of the directory to be removed | ||
510 | * | ||
511 | * Assumes Glocks on dip and ip are held | ||
512 | * | ||
513 | * Returns: errno | ||
514 | */ | ||
515 | |||
516 | static int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | ||
517 | struct gfs2_inode *ip) | ||
518 | { | ||
519 | int error; | ||
520 | |||
521 | if (ip->i_entries != 2) { | ||
522 | if (gfs2_consist_inode(ip)) | ||
523 | gfs2_dinode_print(ip); | ||
524 | return -EIO; | ||
525 | } | ||
526 | |||
527 | error = gfs2_dir_del(dip, name); | ||
528 | if (error) | ||
529 | return error; | ||
530 | |||
531 | error = gfs2_change_nlink(dip, -1); | ||
532 | if (error) | ||
533 | return error; | ||
534 | |||
535 | error = gfs2_dir_del(ip, &gfs2_qdot); | ||
536 | if (error) | ||
537 | return error; | ||
538 | |||
539 | error = gfs2_dir_del(ip, &gfs2_qdotdot); | ||
540 | if (error) | ||
541 | return error; | ||
542 | |||
543 | /* It looks odd, but it really should be done twice */ | ||
544 | error = gfs2_change_nlink(ip, -1); | ||
545 | if (error) | ||
546 | return error; | ||
547 | |||
548 | error = gfs2_change_nlink(ip, -1); | ||
549 | if (error) | ||
550 | return error; | ||
551 | |||
552 | return error; | ||
553 | } | ||
554 | |||
555 | /** | ||
556 | * gfs2_rmdir - Remove a directory | ||
557 | * @dir: The parent directory of the directory to be removed | ||
558 | * @dentry: The dentry of the directory to remove | ||
559 | * | ||
560 | * Remove a directory. Call gfs2_rmdiri() | ||
561 | * | ||
562 | * Returns: errno | ||
563 | */ | ||
564 | |||
565 | static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) | ||
566 | { | ||
567 | struct gfs2_inode *dip = GFS2_I(dir); | ||
568 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
569 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
570 | struct gfs2_holder ghs[3]; | ||
571 | struct gfs2_rgrpd *rgd; | ||
572 | struct gfs2_holder ri_gh; | ||
573 | int error; | ||
574 | |||
575 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
576 | if (error) | ||
577 | return error; | ||
578 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | ||
579 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1); | ||
580 | |||
581 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | ||
582 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | ||
583 | |||
584 | error = gfs2_glock_nq(ghs); /* parent */ | ||
585 | if (error) | ||
586 | goto out_parent; | ||
587 | |||
588 | error = gfs2_glock_nq(ghs + 1); /* child */ | ||
589 | if (error) | ||
590 | goto out_child; | ||
591 | |||
592 | error = gfs2_glock_nq(ghs + 2); /* rgrp */ | ||
593 | if (error) | ||
594 | goto out_rgrp; | ||
595 | |||
596 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); | ||
597 | if (error) | ||
598 | goto out_gunlock; | ||
599 | |||
600 | if (ip->i_entries < 2) { | ||
601 | if (gfs2_consist_inode(ip)) | ||
602 | gfs2_dinode_print(ip); | ||
603 | error = -EIO; | ||
604 | goto out_gunlock; | ||
605 | } | ||
606 | if (ip->i_entries > 2) { | ||
607 | error = -ENOTEMPTY; | ||
608 | goto out_gunlock; | ||
609 | } | ||
610 | |||
611 | error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF + RES_RG_BIT, 0); | ||
612 | if (error) | ||
613 | goto out_gunlock; | ||
614 | |||
615 | error = gfs2_rmdiri(dip, &dentry->d_name, ip); | ||
616 | |||
617 | gfs2_trans_end(sdp); | ||
618 | |||
619 | out_gunlock: | ||
620 | gfs2_glock_dq(ghs + 2); | ||
621 | out_rgrp: | ||
622 | gfs2_holder_uninit(ghs + 2); | ||
623 | gfs2_glock_dq(ghs + 1); | ||
624 | out_child: | ||
625 | gfs2_holder_uninit(ghs + 1); | ||
626 | gfs2_glock_dq(ghs); | ||
627 | out_parent: | ||
628 | gfs2_holder_uninit(ghs); | ||
629 | gfs2_glock_dq_uninit(&ri_gh); | ||
630 | return error; | ||
631 | } | ||
632 | |||
633 | /** | ||
634 | * gfs2_mknod - Make a special file | ||
635 | * @dir: The directory in which the special file will reside | ||
636 | * @dentry: The dentry of the special file | ||
637 | * @mode: The mode of the special file | ||
638 | * @rdev: The device specification of the special file | ||
639 | * | ||
640 | */ | ||
641 | |||
642 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, | ||
643 | dev_t dev) | ||
644 | { | ||
645 | struct gfs2_inode *dip = GFS2_I(dir); | ||
646 | struct gfs2_sbd *sdp = GFS2_SB(dir); | ||
647 | struct gfs2_holder ghs[2]; | ||
648 | struct inode *inode; | ||
649 | |||
650 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | ||
651 | |||
652 | inode = gfs2_createi(ghs, &dentry->d_name, mode, dev); | ||
653 | if (IS_ERR(inode)) { | ||
654 | gfs2_holder_uninit(ghs); | ||
655 | return PTR_ERR(inode); | ||
656 | } | ||
657 | |||
658 | gfs2_trans_end(sdp); | ||
659 | if (dip->i_alloc->al_rgd) | ||
660 | gfs2_inplace_release(dip); | ||
661 | gfs2_quota_unlock(dip); | ||
662 | gfs2_alloc_put(dip); | ||
663 | |||
664 | gfs2_glock_dq_uninit_m(2, ghs); | ||
665 | |||
666 | d_instantiate(dentry, inode); | ||
667 | mark_inode_dirty(inode); | ||
668 | |||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | /* | ||
673 | * gfs2_ok_to_move - check if it's ok to move a directory to another directory | ||
674 | * @this: move this | ||
675 | * @to: to here | ||
676 | * | ||
677 | * Follow @to back to the root and make sure we don't encounter @this | ||
678 | * Assumes we already hold the rename lock. | ||
679 | * | ||
680 | * Returns: errno | ||
681 | */ | ||
682 | |||
683 | static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) | ||
684 | { | ||
685 | struct inode *dir = &to->i_inode; | ||
686 | struct super_block *sb = dir->i_sb; | ||
687 | struct inode *tmp; | ||
688 | int error = 0; | ||
689 | |||
690 | igrab(dir); | ||
691 | |||
692 | for (;;) { | ||
693 | if (dir == &this->i_inode) { | ||
694 | error = -EINVAL; | ||
695 | break; | ||
696 | } | ||
697 | if (dir == sb->s_root->d_inode) { | ||
698 | error = 0; | ||
699 | break; | ||
700 | } | ||
701 | |||
702 | tmp = gfs2_lookupi(dir, &gfs2_qdotdot, 1); | ||
703 | if (IS_ERR(tmp)) { | ||
704 | error = PTR_ERR(tmp); | ||
705 | break; | ||
706 | } | ||
707 | |||
708 | iput(dir); | ||
709 | dir = tmp; | ||
710 | } | ||
711 | |||
712 | iput(dir); | ||
713 | |||
714 | return error; | ||
715 | } | ||
716 | |||
717 | /** | ||
718 | * gfs2_rename - Rename a file | ||
719 | * @odir: Parent directory of old file name | ||
720 | * @odentry: The old dentry of the file | ||
721 | * @ndir: Parent directory of new file name | ||
722 | * @ndentry: The new dentry of the file | ||
723 | * | ||
724 | * Returns: errno | ||
725 | */ | ||
726 | |||
727 | static int gfs2_rename(struct inode *odir, struct dentry *odentry, | ||
728 | struct inode *ndir, struct dentry *ndentry) | ||
729 | { | ||
730 | struct gfs2_inode *odip = GFS2_I(odir); | ||
731 | struct gfs2_inode *ndip = GFS2_I(ndir); | ||
732 | struct gfs2_inode *ip = GFS2_I(odentry->d_inode); | ||
733 | struct gfs2_inode *nip = NULL; | ||
734 | struct gfs2_sbd *sdp = GFS2_SB(odir); | ||
735 | struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, }, ri_gh; | ||
736 | struct gfs2_rgrpd *nrgd; | ||
737 | unsigned int num_gh; | ||
738 | int dir_rename = 0; | ||
739 | int alloc_required = 0; | ||
740 | unsigned int x; | ||
741 | int error; | ||
742 | |||
743 | if (ndentry->d_inode) { | ||
744 | nip = GFS2_I(ndentry->d_inode); | ||
745 | if (ip == nip) | ||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
750 | if (error) | ||
751 | return error; | ||
752 | |||
753 | if (odip != ndip) { | ||
754 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, | ||
755 | 0, &r_gh); | ||
756 | if (error) | ||
757 | goto out; | ||
758 | |||
759 | if (S_ISDIR(ip->i_inode.i_mode)) { | ||
760 | dir_rename = 1; | ||
761 | /* don't move a dirctory into it's subdir */ | ||
762 | error = gfs2_ok_to_move(ip, ndip); | ||
763 | if (error) | ||
764 | goto out_gunlock_r; | ||
765 | } | ||
766 | } | ||
767 | |||
768 | num_gh = 1; | ||
769 | gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | ||
770 | if (odip != ndip) { | ||
771 | gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); | ||
772 | num_gh++; | ||
773 | } | ||
774 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); | ||
775 | num_gh++; | ||
776 | |||
777 | if (nip) { | ||
778 | gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh); | ||
779 | num_gh++; | ||
780 | /* grab the resource lock for unlink flag twiddling | ||
781 | * this is the case of the target file already existing | ||
782 | * so we unlink before doing the rename | ||
783 | */ | ||
784 | nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr); | ||
785 | if (nrgd) | ||
786 | gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++); | ||
787 | } | ||
788 | |||
789 | for (x = 0; x < num_gh; x++) { | ||
790 | error = gfs2_glock_nq(ghs + x); | ||
791 | if (error) | ||
792 | goto out_gunlock; | ||
793 | } | ||
794 | |||
795 | /* Check out the old directory */ | ||
796 | |||
797 | error = gfs2_unlink_ok(odip, &odentry->d_name, ip); | ||
798 | if (error) | ||
799 | goto out_gunlock; | ||
800 | |||
801 | /* Check out the new directory */ | ||
802 | |||
803 | if (nip) { | ||
804 | error = gfs2_unlink_ok(ndip, &ndentry->d_name, nip); | ||
805 | if (error) | ||
806 | goto out_gunlock; | ||
807 | |||
808 | if (S_ISDIR(nip->i_inode.i_mode)) { | ||
809 | if (nip->i_entries < 2) { | ||
810 | if (gfs2_consist_inode(nip)) | ||
811 | gfs2_dinode_print(nip); | ||
812 | error = -EIO; | ||
813 | goto out_gunlock; | ||
814 | } | ||
815 | if (nip->i_entries > 2) { | ||
816 | error = -ENOTEMPTY; | ||
817 | goto out_gunlock; | ||
818 | } | ||
819 | } | ||
820 | } else { | ||
821 | error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC, 0); | ||
822 | if (error) | ||
823 | goto out_gunlock; | ||
824 | |||
825 | error = gfs2_dir_check(ndir, &ndentry->d_name, NULL); | ||
826 | switch (error) { | ||
827 | case -ENOENT: | ||
828 | error = 0; | ||
829 | break; | ||
830 | case 0: | ||
831 | error = -EEXIST; | ||
832 | default: | ||
833 | goto out_gunlock; | ||
834 | }; | ||
835 | |||
836 | if (odip != ndip) { | ||
837 | if (!ndip->i_inode.i_nlink) { | ||
838 | error = -EINVAL; | ||
839 | goto out_gunlock; | ||
840 | } | ||
841 | if (ndip->i_entries == (u32)-1) { | ||
842 | error = -EFBIG; | ||
843 | goto out_gunlock; | ||
844 | } | ||
845 | if (S_ISDIR(ip->i_inode.i_mode) && | ||
846 | ndip->i_inode.i_nlink == (u32)-1) { | ||
847 | error = -EMLINK; | ||
848 | goto out_gunlock; | ||
849 | } | ||
850 | } | ||
851 | } | ||
852 | |||
853 | /* Check out the dir to be renamed */ | ||
854 | |||
855 | if (dir_rename) { | ||
856 | error = gfs2_permission(odentry->d_inode, MAY_WRITE, 0); | ||
857 | if (error) | ||
858 | goto out_gunlock; | ||
859 | } | ||
860 | |||
861 | if (nip == NULL) | ||
862 | alloc_required = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); | ||
863 | error = alloc_required; | ||
864 | if (error < 0) | ||
865 | goto out_gunlock; | ||
866 | error = 0; | ||
867 | |||
868 | if (alloc_required) { | ||
869 | struct gfs2_alloc *al = gfs2_alloc_get(ndip); | ||
870 | if (!al) { | ||
871 | error = -ENOMEM; | ||
872 | goto out_gunlock; | ||
873 | } | ||
874 | |||
875 | error = gfs2_quota_lock_check(ndip); | ||
876 | if (error) | ||
877 | goto out_alloc; | ||
878 | |||
879 | al->al_requested = sdp->sd_max_dirres; | ||
880 | |||
881 | error = gfs2_inplace_reserve_ri(ndip); | ||
882 | if (error) | ||
883 | goto out_gunlock_q; | ||
884 | |||
885 | error = gfs2_trans_begin(sdp, sdp->sd_max_dirres + | ||
886 | gfs2_rg_blocks(al) + | ||
887 | 4 * RES_DINODE + 4 * RES_LEAF + | ||
888 | RES_STATFS + RES_QUOTA + 4, 0); | ||
889 | if (error) | ||
890 | goto out_ipreserv; | ||
891 | } else { | ||
892 | error = gfs2_trans_begin(sdp, 4 * RES_DINODE + | ||
893 | 5 * RES_LEAF + 4, 0); | ||
894 | if (error) | ||
895 | goto out_gunlock; | ||
896 | } | ||
897 | |||
898 | /* Remove the target file, if it exists */ | ||
899 | |||
900 | if (nip) { | ||
901 | if (S_ISDIR(nip->i_inode.i_mode)) | ||
902 | error = gfs2_rmdiri(ndip, &ndentry->d_name, nip); | ||
903 | else { | ||
904 | error = gfs2_dir_del(ndip, &ndentry->d_name); | ||
905 | if (error) | ||
906 | goto out_end_trans; | ||
907 | error = gfs2_change_nlink(nip, -1); | ||
908 | } | ||
909 | if (error) | ||
910 | goto out_end_trans; | ||
911 | } | ||
912 | |||
913 | if (dir_rename) { | ||
914 | error = gfs2_change_nlink(ndip, +1); | ||
915 | if (error) | ||
916 | goto out_end_trans; | ||
917 | error = gfs2_change_nlink(odip, -1); | ||
918 | if (error) | ||
919 | goto out_end_trans; | ||
920 | |||
921 | error = gfs2_dir_mvino(ip, &gfs2_qdotdot, ndip, DT_DIR); | ||
922 | if (error) | ||
923 | goto out_end_trans; | ||
924 | } else { | ||
925 | struct buffer_head *dibh; | ||
926 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
927 | if (error) | ||
928 | goto out_end_trans; | ||
929 | ip->i_inode.i_ctime = CURRENT_TIME; | ||
930 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
931 | gfs2_dinode_out(ip, dibh->b_data); | ||
932 | brelse(dibh); | ||
933 | } | ||
934 | |||
935 | error = gfs2_dir_del(odip, &odentry->d_name); | ||
936 | if (error) | ||
937 | goto out_end_trans; | ||
938 | |||
939 | error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode)); | ||
940 | if (error) | ||
941 | goto out_end_trans; | ||
942 | |||
943 | out_end_trans: | ||
944 | gfs2_trans_end(sdp); | ||
945 | out_ipreserv: | ||
946 | if (alloc_required) | ||
947 | gfs2_inplace_release(ndip); | ||
948 | out_gunlock_q: | ||
949 | if (alloc_required) | ||
950 | gfs2_quota_unlock(ndip); | ||
951 | out_alloc: | ||
952 | if (alloc_required) | ||
953 | gfs2_alloc_put(ndip); | ||
954 | out_gunlock: | ||
955 | while (x--) { | ||
956 | gfs2_glock_dq(ghs + x); | ||
957 | gfs2_holder_uninit(ghs + x); | ||
958 | } | ||
959 | out_gunlock_r: | ||
960 | if (r_gh.gh_gl) | ||
961 | gfs2_glock_dq_uninit(&r_gh); | ||
962 | out: | ||
963 | gfs2_glock_dq_uninit(&ri_gh); | ||
964 | return error; | ||
965 | } | ||
966 | |||
967 | /** | ||
968 | * gfs2_follow_link - Follow a symbolic link | ||
969 | * @dentry: The dentry of the link | ||
970 | * @nd: Data that we pass to vfs_follow_link() | ||
971 | * | ||
972 | * This can handle symlinks of any size. | ||
973 | * | ||
974 | * Returns: 0 on success or error code | ||
975 | */ | ||
976 | |||
977 | static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) | ||
978 | { | ||
979 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
980 | struct gfs2_holder i_gh; | ||
981 | struct buffer_head *dibh; | ||
982 | unsigned int x, size; | ||
983 | char *buf; | ||
984 | int error; | ||
985 | |||
986 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); | ||
987 | error = gfs2_glock_nq(&i_gh); | ||
988 | if (error) { | ||
989 | gfs2_holder_uninit(&i_gh); | ||
990 | nd_set_link(nd, ERR_PTR(error)); | ||
991 | return NULL; | ||
992 | } | ||
993 | |||
994 | size = (unsigned int)i_size_read(&ip->i_inode); | ||
995 | if (size == 0) { | ||
996 | gfs2_consist_inode(ip); | ||
997 | buf = ERR_PTR(-EIO); | ||
998 | goto out; | ||
999 | } | ||
1000 | |||
1001 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
1002 | if (error) { | ||
1003 | buf = ERR_PTR(error); | ||
1004 | goto out; | ||
1005 | } | ||
1006 | |||
1007 | x = size + 1; | ||
1008 | buf = kmalloc(x, GFP_NOFS); | ||
1009 | if (!buf) | ||
1010 | buf = ERR_PTR(-ENOMEM); | ||
1011 | else | ||
1012 | memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), x); | ||
1013 | brelse(dibh); | ||
1014 | out: | ||
1015 | gfs2_glock_dq_uninit(&i_gh); | ||
1016 | nd_set_link(nd, buf); | ||
1017 | return NULL; | ||
1018 | } | ||
1019 | |||
1020 | static void gfs2_put_link(struct dentry *dentry, struct nameidata *nd, void *p) | ||
1021 | { | ||
1022 | char *s = nd_get_link(nd); | ||
1023 | if (!IS_ERR(s)) | ||
1024 | kfree(s); | ||
1025 | } | ||
1026 | |||
1027 | /** | ||
1028 | * gfs2_permission - | ||
1029 | * @inode: The inode | ||
1030 | * @mask: The mask to be tested | ||
1031 | * @flags: Indicates whether this is an RCU path walk or not | ||
1032 | * | ||
1033 | * This may be called from the VFS directly, or from within GFS2 with the | ||
1034 | * inode locked, so we look to see if the glock is already locked and only | ||
1035 | * lock the glock if its not already been done. | ||
1036 | * | ||
1037 | * Returns: errno | ||
1038 | */ | ||
1039 | |||
1040 | int gfs2_permission(struct inode *inode, int mask, unsigned int flags) | ||
1041 | { | ||
1042 | struct gfs2_inode *ip; | ||
1043 | struct gfs2_holder i_gh; | ||
1044 | int error; | ||
1045 | int unlock = 0; | ||
1046 | |||
1047 | |||
1048 | ip = GFS2_I(inode); | ||
1049 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { | ||
1050 | if (flags & IPERM_FLAG_RCU) | ||
1051 | return -ECHILD; | ||
1052 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | ||
1053 | if (error) | ||
1054 | return error; | ||
1055 | unlock = 1; | ||
1056 | } | ||
1057 | |||
1058 | if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) | ||
1059 | error = -EACCES; | ||
1060 | else | ||
1061 | error = generic_permission(inode, mask, flags, gfs2_check_acl); | ||
1062 | if (unlock) | ||
1063 | gfs2_glock_dq_uninit(&i_gh); | ||
1064 | |||
1065 | return error; | ||
1066 | } | ||
1067 | |||
1068 | static int setattr_chown(struct inode *inode, struct iattr *attr) | ||
1069 | { | ||
1070 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1071 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
1072 | u32 ouid, ogid, nuid, ngid; | ||
1073 | int error; | ||
1074 | |||
1075 | ouid = inode->i_uid; | ||
1076 | ogid = inode->i_gid; | ||
1077 | nuid = attr->ia_uid; | ||
1078 | ngid = attr->ia_gid; | ||
1079 | |||
1080 | if (!(attr->ia_valid & ATTR_UID) || ouid == nuid) | ||
1081 | ouid = nuid = NO_QUOTA_CHANGE; | ||
1082 | if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) | ||
1083 | ogid = ngid = NO_QUOTA_CHANGE; | ||
1084 | |||
1085 | if (!gfs2_alloc_get(ip)) | ||
1086 | return -ENOMEM; | ||
1087 | |||
1088 | error = gfs2_quota_lock(ip, nuid, ngid); | ||
1089 | if (error) | ||
1090 | goto out_alloc; | ||
1091 | |||
1092 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | ||
1093 | error = gfs2_quota_check(ip, nuid, ngid); | ||
1094 | if (error) | ||
1095 | goto out_gunlock_q; | ||
1096 | } | ||
1097 | |||
1098 | error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_QUOTA, 0); | ||
1099 | if (error) | ||
1100 | goto out_gunlock_q; | ||
1101 | |||
1102 | error = gfs2_setattr_simple(ip, attr); | ||
1103 | if (error) | ||
1104 | goto out_end_trans; | ||
1105 | |||
1106 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | ||
1107 | u64 blocks = gfs2_get_inode_blocks(&ip->i_inode); | ||
1108 | gfs2_quota_change(ip, -blocks, ouid, ogid); | ||
1109 | gfs2_quota_change(ip, blocks, nuid, ngid); | ||
1110 | } | ||
1111 | |||
1112 | out_end_trans: | ||
1113 | gfs2_trans_end(sdp); | ||
1114 | out_gunlock_q: | ||
1115 | gfs2_quota_unlock(ip); | ||
1116 | out_alloc: | ||
1117 | gfs2_alloc_put(ip); | ||
1118 | return error; | ||
1119 | } | ||
1120 | |||
1121 | /** | ||
1122 | * gfs2_setattr - Change attributes on an inode | ||
1123 | * @dentry: The dentry which is changing | ||
1124 | * @attr: The structure describing the change | ||
1125 | * | ||
1126 | * The VFS layer wants to change one or more of an inodes attributes. Write | ||
1127 | * that change out to disk. | ||
1128 | * | ||
1129 | * Returns: errno | ||
1130 | */ | ||
1131 | |||
1132 | static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) | ||
1133 | { | ||
1134 | struct inode *inode = dentry->d_inode; | ||
1135 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1136 | struct gfs2_holder i_gh; | ||
1137 | int error; | ||
1138 | |||
1139 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); | ||
1140 | if (error) | ||
1141 | return error; | ||
1142 | |||
1143 | error = -EPERM; | ||
1144 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | ||
1145 | goto out; | ||
1146 | |||
1147 | error = inode_change_ok(inode, attr); | ||
1148 | if (error) | ||
1149 | goto out; | ||
1150 | |||
1151 | if (attr->ia_valid & ATTR_SIZE) | ||
1152 | error = gfs2_setattr_size(inode, attr->ia_size); | ||
1153 | else if (attr->ia_valid & (ATTR_UID | ATTR_GID)) | ||
1154 | error = setattr_chown(inode, attr); | ||
1155 | else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode)) | ||
1156 | error = gfs2_acl_chmod(ip, attr); | ||
1157 | else | ||
1158 | error = gfs2_setattr_simple(ip, attr); | ||
1159 | |||
1160 | out: | ||
1161 | gfs2_glock_dq_uninit(&i_gh); | ||
1162 | if (!error) | ||
1163 | mark_inode_dirty(inode); | ||
1164 | return error; | ||
1165 | } | ||
1166 | |||
1167 | /** | ||
1168 | * gfs2_getattr - Read out an inode's attributes | ||
1169 | * @mnt: The vfsmount the inode is being accessed from | ||
1170 | * @dentry: The dentry to stat | ||
1171 | * @stat: The inode's stats | ||
1172 | * | ||
1173 | * This may be called from the VFS directly, or from within GFS2 with the | ||
1174 | * inode locked, so we look to see if the glock is already locked and only | ||
1175 | * lock the glock if its not already been done. Note that its the NFS | ||
1176 | * readdirplus operation which causes this to be called (from filldir) | ||
1177 | * with the glock already held. | ||
1178 | * | ||
1179 | * Returns: errno | ||
1180 | */ | ||
1181 | |||
1182 | static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
1183 | struct kstat *stat) | ||
1184 | { | ||
1185 | struct inode *inode = dentry->d_inode; | ||
1186 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1187 | struct gfs2_holder gh; | ||
1188 | int error; | ||
1189 | int unlock = 0; | ||
1190 | |||
1191 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { | ||
1192 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | ||
1193 | if (error) | ||
1194 | return error; | ||
1195 | unlock = 1; | ||
1196 | } | ||
1197 | |||
1198 | generic_fillattr(inode, stat); | ||
1199 | if (unlock) | ||
1200 | gfs2_glock_dq_uninit(&gh); | ||
1201 | |||
1202 | return 0; | ||
1203 | } | ||
1204 | |||
1205 | static int gfs2_setxattr(struct dentry *dentry, const char *name, | ||
1206 | const void *data, size_t size, int flags) | ||
1207 | { | ||
1208 | struct inode *inode = dentry->d_inode; | ||
1209 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1210 | struct gfs2_holder gh; | ||
1211 | int ret; | ||
1212 | |||
1213 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
1214 | ret = gfs2_glock_nq(&gh); | ||
1215 | if (ret == 0) { | ||
1216 | ret = generic_setxattr(dentry, name, data, size, flags); | ||
1217 | gfs2_glock_dq(&gh); | ||
1218 | } | ||
1219 | gfs2_holder_uninit(&gh); | ||
1220 | return ret; | ||
1221 | } | ||
1222 | |||
1223 | static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name, | ||
1224 | void *data, size_t size) | ||
1225 | { | ||
1226 | struct inode *inode = dentry->d_inode; | ||
1227 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1228 | struct gfs2_holder gh; | ||
1229 | int ret; | ||
1230 | |||
1231 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | ||
1232 | ret = gfs2_glock_nq(&gh); | ||
1233 | if (ret == 0) { | ||
1234 | ret = generic_getxattr(dentry, name, data, size); | ||
1235 | gfs2_glock_dq(&gh); | ||
1236 | } | ||
1237 | gfs2_holder_uninit(&gh); | ||
1238 | return ret; | ||
1239 | } | ||
1240 | |||
1241 | static int gfs2_removexattr(struct dentry *dentry, const char *name) | ||
1242 | { | ||
1243 | struct inode *inode = dentry->d_inode; | ||
1244 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1245 | struct gfs2_holder gh; | ||
1246 | int ret; | ||
1247 | |||
1248 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
1249 | ret = gfs2_glock_nq(&gh); | ||
1250 | if (ret == 0) { | ||
1251 | ret = generic_removexattr(dentry, name); | ||
1252 | gfs2_glock_dq(&gh); | ||
1253 | } | ||
1254 | gfs2_holder_uninit(&gh); | ||
1255 | return ret; | ||
1256 | } | ||
1257 | |||
1258 | static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | ||
1259 | u64 start, u64 len) | ||
1260 | { | ||
1261 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1262 | struct gfs2_holder gh; | ||
1263 | int ret; | ||
1264 | |||
1265 | ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); | ||
1266 | if (ret) | ||
1267 | return ret; | ||
1268 | |||
1269 | mutex_lock(&inode->i_mutex); | ||
1270 | |||
1271 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | ||
1272 | if (ret) | ||
1273 | goto out; | ||
1274 | |||
1275 | if (gfs2_is_stuffed(ip)) { | ||
1276 | u64 phys = ip->i_no_addr << inode->i_blkbits; | ||
1277 | u64 size = i_size_read(inode); | ||
1278 | u32 flags = FIEMAP_EXTENT_LAST|FIEMAP_EXTENT_NOT_ALIGNED| | ||
1279 | FIEMAP_EXTENT_DATA_INLINE; | ||
1280 | phys += sizeof(struct gfs2_dinode); | ||
1281 | phys += start; | ||
1282 | if (start + len > size) | ||
1283 | len = size - start; | ||
1284 | if (start < size) | ||
1285 | ret = fiemap_fill_next_extent(fieinfo, start, phys, | ||
1286 | len, flags); | ||
1287 | if (ret == 1) | ||
1288 | ret = 0; | ||
1289 | } else { | ||
1290 | ret = __generic_block_fiemap(inode, fieinfo, start, len, | ||
1291 | gfs2_block_map); | ||
1292 | } | ||
1293 | |||
1294 | gfs2_glock_dq_uninit(&gh); | ||
1295 | out: | ||
1296 | mutex_unlock(&inode->i_mutex); | ||
1297 | return ret; | ||
1298 | } | ||
1299 | |||
1300 | const struct inode_operations gfs2_file_iops = { | ||
1301 | .permission = gfs2_permission, | ||
1302 | .setattr = gfs2_setattr, | ||
1303 | .getattr = gfs2_getattr, | ||
1304 | .setxattr = gfs2_setxattr, | ||
1305 | .getxattr = gfs2_getxattr, | ||
1306 | .listxattr = gfs2_listxattr, | ||
1307 | .removexattr = gfs2_removexattr, | ||
1308 | .fiemap = gfs2_fiemap, | ||
1309 | }; | ||
1310 | |||
1311 | const struct inode_operations gfs2_dir_iops = { | ||
1312 | .create = gfs2_create, | ||
1313 | .lookup = gfs2_lookup, | ||
1314 | .link = gfs2_link, | ||
1315 | .unlink = gfs2_unlink, | ||
1316 | .symlink = gfs2_symlink, | ||
1317 | .mkdir = gfs2_mkdir, | ||
1318 | .rmdir = gfs2_rmdir, | ||
1319 | .mknod = gfs2_mknod, | ||
1320 | .rename = gfs2_rename, | ||
1321 | .permission = gfs2_permission, | ||
1322 | .setattr = gfs2_setattr, | ||
1323 | .getattr = gfs2_getattr, | ||
1324 | .setxattr = gfs2_setxattr, | ||
1325 | .getxattr = gfs2_getxattr, | ||
1326 | .listxattr = gfs2_listxattr, | ||
1327 | .removexattr = gfs2_removexattr, | ||
1328 | .fiemap = gfs2_fiemap, | ||
1329 | }; | ||
1330 | |||
1331 | const struct inode_operations gfs2_symlink_iops = { | ||
1332 | .readlink = generic_readlink, | ||
1333 | .follow_link = gfs2_follow_link, | ||
1334 | .put_link = gfs2_put_link, | ||
1335 | .permission = gfs2_permission, | ||
1336 | .setattr = gfs2_setattr, | ||
1337 | .getattr = gfs2_getattr, | ||
1338 | .setxattr = gfs2_setxattr, | ||
1339 | .getxattr = gfs2_getxattr, | ||
1340 | .listxattr = gfs2_listxattr, | ||
1341 | .removexattr = gfs2_removexattr, | ||
1342 | .fiemap = gfs2_fiemap, | ||
1343 | }; | ||
1344 | |||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 6fcae8469f6d..7273ad3c85ba 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -78,10 +78,11 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
78 | 78 | ||
79 | static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf1, | 79 | static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf1, |
80 | unsigned char *buf2, unsigned int offset, | 80 | unsigned char *buf2, unsigned int offset, |
81 | unsigned int buflen, u32 block, | 81 | struct gfs2_bitmap *bi, u32 block, |
82 | unsigned char new_state) | 82 | unsigned char new_state) |
83 | { | 83 | { |
84 | unsigned char *byte1, *byte2, *end, cur_state; | 84 | unsigned char *byte1, *byte2, *end, cur_state; |
85 | unsigned int buflen = bi->bi_len; | ||
85 | const unsigned int bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE; | 86 | const unsigned int bit = (block % GFS2_NBBY) * GFS2_BIT_SIZE; |
86 | 87 | ||
87 | byte1 = buf1 + offset + (block / GFS2_NBBY); | 88 | byte1 = buf1 + offset + (block / GFS2_NBBY); |
@@ -92,6 +93,16 @@ static inline void gfs2_setbit(struct gfs2_rgrpd *rgd, unsigned char *buf1, | |||
92 | cur_state = (*byte1 >> bit) & GFS2_BIT_MASK; | 93 | cur_state = (*byte1 >> bit) & GFS2_BIT_MASK; |
93 | 94 | ||
94 | if (unlikely(!valid_change[new_state * 4 + cur_state])) { | 95 | if (unlikely(!valid_change[new_state * 4 + cur_state])) { |
96 | printk(KERN_WARNING "GFS2: buf_blk = 0x%llx old_state=%d, " | ||
97 | "new_state=%d\n", | ||
98 | (unsigned long long)block, cur_state, new_state); | ||
99 | printk(KERN_WARNING "GFS2: rgrp=0x%llx bi_start=0x%lx\n", | ||
100 | (unsigned long long)rgd->rd_addr, | ||
101 | (unsigned long)bi->bi_start); | ||
102 | printk(KERN_WARNING "GFS2: bi_offset=0x%lx bi_len=0x%lx\n", | ||
103 | (unsigned long)bi->bi_offset, | ||
104 | (unsigned long)bi->bi_len); | ||
105 | dump_stack(); | ||
95 | gfs2_consist_rgrpd(rgd); | 106 | gfs2_consist_rgrpd(rgd); |
96 | return; | 107 | return; |
97 | } | 108 | } |
@@ -381,6 +392,7 @@ static void clear_rgrpdi(struct gfs2_sbd *sdp) | |||
381 | 392 | ||
382 | if (gl) { | 393 | if (gl) { |
383 | gl->gl_object = NULL; | 394 | gl->gl_object = NULL; |
395 | gfs2_glock_add_to_lru(gl); | ||
384 | gfs2_glock_put(gl); | 396 | gfs2_glock_put(gl); |
385 | } | 397 | } |
386 | 398 | ||
@@ -1365,7 +1377,7 @@ skip: | |||
1365 | 1377 | ||
1366 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1378 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
1367 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, | 1379 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, |
1368 | bi->bi_len, blk, new_state); | 1380 | bi, blk, new_state); |
1369 | goal = blk; | 1381 | goal = blk; |
1370 | while (*n < elen) { | 1382 | while (*n < elen) { |
1371 | goal++; | 1383 | goal++; |
@@ -1375,7 +1387,7 @@ skip: | |||
1375 | GFS2_BLKST_FREE) | 1387 | GFS2_BLKST_FREE) |
1376 | break; | 1388 | break; |
1377 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, | 1389 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, |
1378 | bi->bi_len, goal, new_state); | 1390 | bi, goal, new_state); |
1379 | (*n)++; | 1391 | (*n)++; |
1380 | } | 1392 | } |
1381 | out: | 1393 | out: |
@@ -1432,7 +1444,7 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, | |||
1432 | } | 1444 | } |
1433 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1445 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
1434 | gfs2_setbit(rgd, bi->bi_bh->b_data, NULL, bi->bi_offset, | 1446 | gfs2_setbit(rgd, bi->bi_bh->b_data, NULL, bi->bi_offset, |
1435 | bi->bi_len, buf_blk, new_state); | 1447 | bi, buf_blk, new_state); |
1436 | } | 1448 | } |
1437 | 1449 | ||
1438 | return rgd; | 1450 | return rgd; |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index b9f28e66dad1..ed540e7018be 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/time.h> | 23 | #include <linux/time.h> |
24 | #include <linux/wait.h> | 24 | #include <linux/wait.h> |
25 | #include <linux/writeback.h> | 25 | #include <linux/writeback.h> |
26 | #include <linux/backing-dev.h> | ||
26 | 27 | ||
27 | #include "gfs2.h" | 28 | #include "gfs2.h" |
28 | #include "incore.h" | 29 | #include "incore.h" |
@@ -700,11 +701,47 @@ void gfs2_unfreeze_fs(struct gfs2_sbd *sdp) | |||
700 | mutex_unlock(&sdp->sd_freeze_lock); | 701 | mutex_unlock(&sdp->sd_freeze_lock); |
701 | } | 702 | } |
702 | 703 | ||
704 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | ||
705 | { | ||
706 | struct gfs2_dinode *str = buf; | ||
707 | |||
708 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | ||
709 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); | ||
710 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); | ||
711 | str->di_num.no_addr = cpu_to_be64(ip->i_no_addr); | ||
712 | str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino); | ||
713 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); | ||
714 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); | ||
715 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | ||
716 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | ||
717 | str->di_size = cpu_to_be64(i_size_read(&ip->i_inode)); | ||
718 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); | ||
719 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | ||
720 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); | ||
721 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); | ||
722 | |||
723 | str->di_goal_meta = cpu_to_be64(ip->i_goal); | ||
724 | str->di_goal_data = cpu_to_be64(ip->i_goal); | ||
725 | str->di_generation = cpu_to_be64(ip->i_generation); | ||
726 | |||
727 | str->di_flags = cpu_to_be32(ip->i_diskflags); | ||
728 | str->di_height = cpu_to_be16(ip->i_height); | ||
729 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | ||
730 | !(ip->i_diskflags & GFS2_DIF_EXHASH) ? | ||
731 | GFS2_FORMAT_DE : 0); | ||
732 | str->di_depth = cpu_to_be16(ip->i_depth); | ||
733 | str->di_entries = cpu_to_be32(ip->i_entries); | ||
734 | |||
735 | str->di_eattr = cpu_to_be64(ip->i_eattr); | ||
736 | str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); | ||
737 | str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); | ||
738 | str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); | ||
739 | } | ||
703 | 740 | ||
704 | /** | 741 | /** |
705 | * gfs2_write_inode - Make sure the inode is stable on the disk | 742 | * gfs2_write_inode - Make sure the inode is stable on the disk |
706 | * @inode: The inode | 743 | * @inode: The inode |
707 | * @sync: synchronous write flag | 744 | * @wbc: The writeback control structure |
708 | * | 745 | * |
709 | * Returns: errno | 746 | * Returns: errno |
710 | */ | 747 | */ |
@@ -713,15 +750,17 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
713 | { | 750 | { |
714 | struct gfs2_inode *ip = GFS2_I(inode); | 751 | struct gfs2_inode *ip = GFS2_I(inode); |
715 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 752 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
753 | struct address_space *metamapping = gfs2_glock2aspace(ip->i_gl); | ||
754 | struct backing_dev_info *bdi = metamapping->backing_dev_info; | ||
716 | struct gfs2_holder gh; | 755 | struct gfs2_holder gh; |
717 | struct buffer_head *bh; | 756 | struct buffer_head *bh; |
718 | struct timespec atime; | 757 | struct timespec atime; |
719 | struct gfs2_dinode *di; | 758 | struct gfs2_dinode *di; |
720 | int ret = 0; | 759 | int ret = -EAGAIN; |
721 | 760 | ||
722 | /* Check this is a "normal" inode, etc */ | 761 | /* Skip timestamp update, if this is from a memalloc */ |
723 | if (current->flags & PF_MEMALLOC) | 762 | if (current->flags & PF_MEMALLOC) |
724 | return 0; | 763 | goto do_flush; |
725 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 764 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
726 | if (ret) | 765 | if (ret) |
727 | goto do_flush; | 766 | goto do_flush; |
@@ -745,6 +784,13 @@ do_unlock: | |||
745 | do_flush: | 784 | do_flush: |
746 | if (wbc->sync_mode == WB_SYNC_ALL) | 785 | if (wbc->sync_mode == WB_SYNC_ALL) |
747 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | 786 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); |
787 | filemap_fdatawrite(metamapping); | ||
788 | if (bdi->dirty_exceeded) | ||
789 | gfs2_ail1_flush(sdp, wbc); | ||
790 | if (!ret && (wbc->sync_mode == WB_SYNC_ALL)) | ||
791 | ret = filemap_fdatawait(metamapping); | ||
792 | if (ret) | ||
793 | mark_inode_dirty_sync(inode); | ||
748 | return ret; | 794 | return ret; |
749 | } | 795 | } |
750 | 796 | ||
@@ -874,8 +920,9 @@ restart: | |||
874 | 920 | ||
875 | static int gfs2_sync_fs(struct super_block *sb, int wait) | 921 | static int gfs2_sync_fs(struct super_block *sb, int wait) |
876 | { | 922 | { |
877 | if (wait && sb->s_fs_info) | 923 | struct gfs2_sbd *sdp = sb->s_fs_info; |
878 | gfs2_log_flush(sb->s_fs_info, NULL); | 924 | if (wait && sdp) |
925 | gfs2_log_flush(sdp, NULL); | ||
879 | return 0; | 926 | return 0; |
880 | } | 927 | } |
881 | 928 | ||
@@ -1308,6 +1355,78 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1308 | return 0; | 1355 | return 0; |
1309 | } | 1356 | } |
1310 | 1357 | ||
1358 | static void gfs2_final_release_pages(struct gfs2_inode *ip) | ||
1359 | { | ||
1360 | struct inode *inode = &ip->i_inode; | ||
1361 | struct gfs2_glock *gl = ip->i_gl; | ||
1362 | |||
1363 | truncate_inode_pages(gfs2_glock2aspace(ip->i_gl), 0); | ||
1364 | truncate_inode_pages(&inode->i_data, 0); | ||
1365 | |||
1366 | if (atomic_read(&gl->gl_revokes) == 0) { | ||
1367 | clear_bit(GLF_LFLUSH, &gl->gl_flags); | ||
1368 | clear_bit(GLF_DIRTY, &gl->gl_flags); | ||
1369 | } | ||
1370 | } | ||
1371 | |||
1372 | static int gfs2_dinode_dealloc(struct gfs2_inode *ip) | ||
1373 | { | ||
1374 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1375 | struct gfs2_alloc *al; | ||
1376 | struct gfs2_rgrpd *rgd; | ||
1377 | int error; | ||
1378 | |||
1379 | if (gfs2_get_inode_blocks(&ip->i_inode) != 1) { | ||
1380 | gfs2_consist_inode(ip); | ||
1381 | return -EIO; | ||
1382 | } | ||
1383 | |||
1384 | al = gfs2_alloc_get(ip); | ||
1385 | if (!al) | ||
1386 | return -ENOMEM; | ||
1387 | |||
1388 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | ||
1389 | if (error) | ||
1390 | goto out; | ||
1391 | |||
1392 | error = gfs2_rindex_hold(sdp, &al->al_ri_gh); | ||
1393 | if (error) | ||
1394 | goto out_qs; | ||
1395 | |||
1396 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); | ||
1397 | if (!rgd) { | ||
1398 | gfs2_consist_inode(ip); | ||
1399 | error = -EIO; | ||
1400 | goto out_rindex_relse; | ||
1401 | } | ||
1402 | |||
1403 | error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, | ||
1404 | &al->al_rgd_gh); | ||
1405 | if (error) | ||
1406 | goto out_rindex_relse; | ||
1407 | |||
1408 | error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_STATFS + RES_QUOTA, | ||
1409 | sdp->sd_jdesc->jd_blocks); | ||
1410 | if (error) | ||
1411 | goto out_rg_gunlock; | ||
1412 | |||
1413 | gfs2_free_di(rgd, ip); | ||
1414 | |||
1415 | gfs2_final_release_pages(ip); | ||
1416 | |||
1417 | gfs2_trans_end(sdp); | ||
1418 | |||
1419 | out_rg_gunlock: | ||
1420 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | ||
1421 | out_rindex_relse: | ||
1422 | gfs2_glock_dq_uninit(&al->al_ri_gh); | ||
1423 | out_qs: | ||
1424 | gfs2_quota_unhold(ip); | ||
1425 | out: | ||
1426 | gfs2_alloc_put(ip); | ||
1427 | return error; | ||
1428 | } | ||
1429 | |||
1311 | /* | 1430 | /* |
1312 | * We have to (at the moment) hold the inodes main lock to cover | 1431 | * We have to (at the moment) hold the inodes main lock to cover |
1313 | * the gap between unlocking the shared lock on the iopen lock and | 1432 | * the gap between unlocking the shared lock on the iopen lock and |
@@ -1371,15 +1490,13 @@ static void gfs2_evict_inode(struct inode *inode) | |||
1371 | } | 1490 | } |
1372 | 1491 | ||
1373 | error = gfs2_dinode_dealloc(ip); | 1492 | error = gfs2_dinode_dealloc(ip); |
1374 | if (error) | 1493 | goto out_unlock; |
1375 | goto out_unlock; | ||
1376 | 1494 | ||
1377 | out_truncate: | 1495 | out_truncate: |
1378 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 1496 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
1379 | if (error) | 1497 | if (error) |
1380 | goto out_unlock; | 1498 | goto out_unlock; |
1381 | /* Needs to be done before glock release & also in a transaction */ | 1499 | gfs2_final_release_pages(ip); |
1382 | truncate_inode_pages(&inode->i_data, 0); | ||
1383 | gfs2_trans_end(sdp); | 1500 | gfs2_trans_end(sdp); |
1384 | 1501 | ||
1385 | out_unlock: | 1502 | out_unlock: |
@@ -1394,6 +1511,7 @@ out: | |||
1394 | end_writeback(inode); | 1511 | end_writeback(inode); |
1395 | 1512 | ||
1396 | ip->i_gl->gl_object = NULL; | 1513 | ip->i_gl->gl_object = NULL; |
1514 | gfs2_glock_add_to_lru(ip->i_gl); | ||
1397 | gfs2_glock_put(ip->i_gl); | 1515 | gfs2_glock_put(ip->i_gl); |
1398 | ip->i_gl = NULL; | 1516 | ip->i_gl = NULL; |
1399 | if (ip->i_iopen_gh.gh_gl) { | 1517 | if (ip->i_iopen_gh.gh_gl) { |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 748ccb557c18..e20eab37bc80 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -81,7 +81,8 @@ static int gfs2_uuid_valid(const u8 *uuid) | |||
81 | 81 | ||
82 | static ssize_t uuid_show(struct gfs2_sbd *sdp, char *buf) | 82 | static ssize_t uuid_show(struct gfs2_sbd *sdp, char *buf) |
83 | { | 83 | { |
84 | const u8 *uuid = sdp->sd_sb.sb_uuid; | 84 | struct super_block *s = sdp->sd_vfs; |
85 | const u8 *uuid = s->s_uuid; | ||
85 | buf[0] = '\0'; | 86 | buf[0] = '\0'; |
86 | if (!gfs2_uuid_valid(uuid)) | 87 | if (!gfs2_uuid_valid(uuid)) |
87 | return 0; | 88 | return 0; |
@@ -616,7 +617,8 @@ static int gfs2_uevent(struct kset *kset, struct kobject *kobj, | |||
616 | struct kobj_uevent_env *env) | 617 | struct kobj_uevent_env *env) |
617 | { | 618 | { |
618 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | 619 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); |
619 | const u8 *uuid = sdp->sd_sb.sb_uuid; | 620 | struct super_block *s = sdp->sd_vfs; |
621 | const u8 *uuid = s->s_uuid; | ||
620 | 622 | ||
621 | add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name); | 623 | add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name); |
622 | add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name); | 624 | add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name); |
diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h index cedb0bb96d96..5d07609ec57d 100644 --- a/fs/gfs2/trace_gfs2.h +++ b/fs/gfs2/trace_gfs2.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/buffer_head.h> | 10 | #include <linux/buffer_head.h> |
11 | #include <linux/dlmconstants.h> | 11 | #include <linux/dlmconstants.h> |
12 | #include <linux/gfs2_ondisk.h> | 12 | #include <linux/gfs2_ondisk.h> |
13 | #include <linux/writeback.h> | ||
13 | #include "incore.h" | 14 | #include "incore.h" |
14 | #include "glock.h" | 15 | #include "glock.h" |
15 | 16 | ||
@@ -40,7 +41,9 @@ | |||
40 | {(1UL << GLF_REPLY_PENDING), "r" }, \ | 41 | {(1UL << GLF_REPLY_PENDING), "r" }, \ |
41 | {(1UL << GLF_INITIAL), "I" }, \ | 42 | {(1UL << GLF_INITIAL), "I" }, \ |
42 | {(1UL << GLF_FROZEN), "F" }, \ | 43 | {(1UL << GLF_FROZEN), "F" }, \ |
43 | {(1UL << GLF_QUEUED), "q" }) | 44 | {(1UL << GLF_QUEUED), "q" }, \ |
45 | {(1UL << GLF_LRU), "L" }, \ | ||
46 | {(1UL << GLF_OBJECT), "o" }) | ||
44 | 47 | ||
45 | #ifndef NUMPTY | 48 | #ifndef NUMPTY |
46 | #define NUMPTY | 49 | #define NUMPTY |
@@ -94,7 +97,7 @@ TRACE_EVENT(gfs2_glock_state_change, | |||
94 | __entry->new_state = glock_trace_state(new_state); | 97 | __entry->new_state = glock_trace_state(new_state); |
95 | __entry->tgt_state = glock_trace_state(gl->gl_target); | 98 | __entry->tgt_state = glock_trace_state(gl->gl_target); |
96 | __entry->dmt_state = glock_trace_state(gl->gl_demote_state); | 99 | __entry->dmt_state = glock_trace_state(gl->gl_demote_state); |
97 | __entry->flags = gl->gl_flags; | 100 | __entry->flags = gl->gl_flags | (gl->gl_object ? (1UL<<GLF_OBJECT) : 0); |
98 | ), | 101 | ), |
99 | 102 | ||
100 | TP_printk("%u,%u glock %d:%lld state %s to %s tgt:%s dmt:%s flags:%s", | 103 | TP_printk("%u,%u glock %d:%lld state %s to %s tgt:%s dmt:%s flags:%s", |
@@ -127,7 +130,7 @@ TRACE_EVENT(gfs2_glock_put, | |||
127 | __entry->gltype = gl->gl_name.ln_type; | 130 | __entry->gltype = gl->gl_name.ln_type; |
128 | __entry->glnum = gl->gl_name.ln_number; | 131 | __entry->glnum = gl->gl_name.ln_number; |
129 | __entry->cur_state = glock_trace_state(gl->gl_state); | 132 | __entry->cur_state = glock_trace_state(gl->gl_state); |
130 | __entry->flags = gl->gl_flags; | 133 | __entry->flags = gl->gl_flags | (gl->gl_object ? (1UL<<GLF_OBJECT) : 0); |
131 | ), | 134 | ), |
132 | 135 | ||
133 | TP_printk("%u,%u glock %d:%lld state %s => %s flags:%s", | 136 | TP_printk("%u,%u glock %d:%lld state %s => %s flags:%s", |
@@ -161,7 +164,7 @@ TRACE_EVENT(gfs2_demote_rq, | |||
161 | __entry->glnum = gl->gl_name.ln_number; | 164 | __entry->glnum = gl->gl_name.ln_number; |
162 | __entry->cur_state = glock_trace_state(gl->gl_state); | 165 | __entry->cur_state = glock_trace_state(gl->gl_state); |
163 | __entry->dmt_state = glock_trace_state(gl->gl_demote_state); | 166 | __entry->dmt_state = glock_trace_state(gl->gl_demote_state); |
164 | __entry->flags = gl->gl_flags; | 167 | __entry->flags = gl->gl_flags | (gl->gl_object ? (1UL<<GLF_OBJECT) : 0); |
165 | ), | 168 | ), |
166 | 169 | ||
167 | TP_printk("%u,%u glock %d:%lld demote %s to %s flags:%s", | 170 | TP_printk("%u,%u glock %d:%lld demote %s to %s flags:%s", |
@@ -318,6 +321,33 @@ TRACE_EVENT(gfs2_log_blocks, | |||
318 | MINOR(__entry->dev), __entry->blocks) | 321 | MINOR(__entry->dev), __entry->blocks) |
319 | ); | 322 | ); |
320 | 323 | ||
324 | /* Writing back the AIL */ | ||
325 | TRACE_EVENT(gfs2_ail_flush, | ||
326 | |||
327 | TP_PROTO(const struct gfs2_sbd *sdp, const struct writeback_control *wbc, int start), | ||
328 | |||
329 | TP_ARGS(sdp, wbc, start), | ||
330 | |||
331 | TP_STRUCT__entry( | ||
332 | __field( dev_t, dev ) | ||
333 | __field( int, start ) | ||
334 | __field( int, sync_mode ) | ||
335 | __field( long, nr_to_write ) | ||
336 | ), | ||
337 | |||
338 | TP_fast_assign( | ||
339 | __entry->dev = sdp->sd_vfs->s_dev; | ||
340 | __entry->start = start; | ||
341 | __entry->sync_mode = wbc->sync_mode; | ||
342 | __entry->nr_to_write = wbc->nr_to_write; | ||
343 | ), | ||
344 | |||
345 | TP_printk("%u,%u ail flush %s %s %ld", MAJOR(__entry->dev), | ||
346 | MINOR(__entry->dev), __entry->start ? "start" : "end", | ||
347 | __entry->sync_mode == WB_SYNC_ALL ? "all" : "none", | ||
348 | __entry->nr_to_write) | ||
349 | ); | ||
350 | |||
321 | /* Section 3 - bmap | 351 | /* Section 3 - bmap |
322 | * | 352 | * |
323 | * Objectives: | 353 | * Objectives: |