aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-06-14 15:32:57 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-06-14 15:32:57 -0400
commitfeaa7bba026c181ce071d5a4884f7f9dd26207a1 (patch)
treec858deb225917265cb07820730e9764674d133e8 /fs/gfs2/glock.c
parent22da645fd6675b7abc55cf937ddf6132f343e5b9 (diff)
[GFS2] Fix unlinked file handling
This patch fixes the way we have been dealing with unlinked, but still open files. It removes all limits (other than memory for inodes, as per every other filesystem) on numbers of these which we can support on GFS2. It also means that (like other fs) its the responsibility of the last process to close the file to deallocate the storage, rather than the person who did the unlinking. Note that with GFS2, those two events might take place on different nodes. Also there are a number of other changes: o We use the Linux inode subsystem as it was intended to be used, wrt allocating GFS2 inodes o The Linux inode cache is now the point which we use for local enforcement of only holding one copy of the inode in core at once (previous to this we used the glock layer). o We no longer use the unlinked "special" file. We just ignore it completely. This makes unlinking more efficient. o We now use the 4th block allocation state. The previously unused state is used to track unlinked but still open inodes. o gfs2_inoded is no longer needed o Several fields are now no longer needed (and removed) from the in core struct gfs2_inode o Several fields are no longer needed (and removed) from the in core superblock There are a number of future possible optimisations and clean ups which have been made possible by this patch. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c102
1 files changed, 21 insertions, 81 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 0603a6de52c9..35bac90878a5 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -654,7 +654,7 @@ static void run_queue(struct gfs2_glock *gl)
654 * Gives caller exclusive access to manipulate a glock structure. 654 * Gives caller exclusive access to manipulate a glock structure.
655 */ 655 */
656 656
657void gfs2_glmutex_lock(struct gfs2_glock *gl) 657static void gfs2_glmutex_lock(struct gfs2_glock *gl)
658{ 658{
659 struct gfs2_holder gh; 659 struct gfs2_holder gh;
660 660
@@ -704,7 +704,7 @@ static int gfs2_glmutex_trylock(struct gfs2_glock *gl)
704 * 704 *
705 */ 705 */
706 706
707void gfs2_glmutex_unlock(struct gfs2_glock *gl) 707static void gfs2_glmutex_unlock(struct gfs2_glock *gl)
708{ 708{
709 spin_lock(&gl->gl_spin); 709 spin_lock(&gl->gl_spin);
710 clear_bit(GLF_LOCK, &gl->gl_flags); 710 clear_bit(GLF_LOCK, &gl->gl_flags);
@@ -726,7 +726,7 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state)
726{ 726{
727 struct gfs2_holder *gh, *new_gh = NULL; 727 struct gfs2_holder *gh, *new_gh = NULL;
728 728
729 restart: 729restart:
730 spin_lock(&gl->gl_spin); 730 spin_lock(&gl->gl_spin);
731 731
732 list_for_each_entry(gh, &gl->gl_waiters2, gh_list) { 732 list_for_each_entry(gh, &gl->gl_waiters2, gh_list) {
@@ -752,13 +752,27 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state)
752 goto restart; 752 goto restart;
753 } 753 }
754 754
755 out: 755out:
756 spin_unlock(&gl->gl_spin); 756 spin_unlock(&gl->gl_spin);
757 757
758 if (new_gh) 758 if (new_gh)
759 gfs2_holder_put(new_gh); 759 gfs2_holder_put(new_gh);
760} 760}
761 761
762void gfs2_glock_inode_squish(struct inode *inode)
763{
764 struct gfs2_holder gh;
765 struct gfs2_glock *gl = GFS2_I(inode)->i_gl;
766 gfs2_holder_init(gl, LM_ST_UNLOCKED, 0, &gh);
767 set_bit(HIF_DEMOTE, &gh.gh_iflags);
768 spin_lock(&gl->gl_spin);
769 gfs2_assert(inode->i_sb->s_fs_info, list_empty(&gl->gl_holders));
770 list_add_tail(&gh.gh_list, &gl->gl_waiters2);
771 run_queue(gl);
772 spin_unlock(&gl->gl_spin);
773 gfs2_holder_uninit(&gh);
774}
775
762/** 776/**
763 * state_change - record that the glock is now in a different state 777 * state_change - record that the glock is now in a different state
764 * @gl: the glock 778 * @gl: the glock
@@ -1383,8 +1397,7 @@ int gfs2_glock_be_greedy(struct gfs2_glock *gl, unsigned int time)
1383 struct greedy *gr; 1397 struct greedy *gr;
1384 struct gfs2_holder *gh; 1398 struct gfs2_holder *gh;
1385 1399
1386 if (!time || 1400 if (!time || gl->gl_sbd->sd_args.ar_localcaching ||
1387 gl->gl_sbd->sd_args.ar_localcaching ||
1388 test_and_set_bit(GLF_GREEDY, &gl->gl_flags)) 1401 test_and_set_bit(GLF_GREEDY, &gl->gl_flags))
1389 return 1; 1402 return 1;
1390 1403
@@ -1785,43 +1798,6 @@ void gfs2_glock_cb(lm_fsdata_t *fsdata, unsigned int type, void *data)
1785} 1798}
1786 1799
1787/** 1800/**
1788 * gfs2_try_toss_inode - try to remove a particular inode struct from cache
1789 * sdp: the filesystem
1790 * inum: the inode number
1791 *
1792 */
1793
1794void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum)
1795{
1796 struct gfs2_glock *gl;
1797 struct gfs2_inode *ip;
1798 int error;
1799
1800 error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops,
1801 NO_CREATE, &gl);
1802 if (error || !gl)
1803 return;
1804
1805 if (!gfs2_glmutex_trylock(gl))
1806 goto out;
1807
1808 ip = gl->gl_object;
1809 if (!ip)
1810 goto out_unlock;
1811
1812 if (atomic_read(&ip->i_count))
1813 goto out_unlock;
1814
1815 gfs2_inode_destroy(ip, 1);
1816
1817 out_unlock:
1818 gfs2_glmutex_unlock(gl);
1819
1820 out:
1821 gfs2_glock_put(gl);
1822}
1823
1824/**
1825 * gfs2_iopen_go_callback - Try to kick the inode/vnode associated with an 1801 * gfs2_iopen_go_callback - Try to kick the inode/vnode associated with an
1826 * iopen glock from memory 1802 * iopen glock from memory
1827 * @io_gl: the iopen glock 1803 * @io_gl: the iopen glock
@@ -1831,34 +1807,10 @@ void gfs2_try_toss_inode(struct gfs2_sbd *sdp, struct gfs2_inum *inum)
1831 1807
1832void gfs2_iopen_go_callback(struct gfs2_glock *io_gl, unsigned int state) 1808void gfs2_iopen_go_callback(struct gfs2_glock *io_gl, unsigned int state)
1833{ 1809{
1834 struct gfs2_glock *i_gl;
1835 1810
1836 if (state != LM_ST_UNLOCKED) 1811 if (state != LM_ST_UNLOCKED)
1837 return; 1812 return;
1838 1813 /* FIXME: remove this? */
1839 spin_lock(&io_gl->gl_spin);
1840 i_gl = io_gl->gl_object;
1841 if (i_gl) {
1842 gfs2_glock_hold(i_gl);
1843 spin_unlock(&io_gl->gl_spin);
1844 } else {
1845 spin_unlock(&io_gl->gl_spin);
1846 return;
1847 }
1848
1849 if (gfs2_glmutex_trylock(i_gl)) {
1850 struct gfs2_inode *ip = i_gl->gl_object;
1851 if (ip) {
1852 gfs2_try_toss_vnode(ip);
1853 gfs2_glmutex_unlock(i_gl);
1854 gfs2_glock_schedule_for_reclaim(i_gl);
1855 goto out;
1856 }
1857 gfs2_glmutex_unlock(i_gl);
1858 }
1859
1860 out:
1861 gfs2_glock_put(i_gl);
1862} 1814}
1863 1815
1864/** 1816/**
@@ -1935,11 +1887,6 @@ void gfs2_reclaim_glock(struct gfs2_sbd *sdp)
1935 atomic_inc(&sdp->sd_reclaimed); 1887 atomic_inc(&sdp->sd_reclaimed);
1936 1888
1937 if (gfs2_glmutex_trylock(gl)) { 1889 if (gfs2_glmutex_trylock(gl)) {
1938 if (gl->gl_ops == &gfs2_inode_glops) {
1939 struct gfs2_inode *ip = gl->gl_object;
1940 if (ip && !atomic_read(&ip->i_count))
1941 gfs2_inode_destroy(ip, 1);
1942 }
1943 if (queue_empty(gl, &gl->gl_holders) && 1890 if (queue_empty(gl, &gl->gl_holders) &&
1944 gl->gl_state != LM_ST_UNLOCKED && 1891 gl->gl_state != LM_ST_UNLOCKED &&
1945 demote_ok(gl)) 1892 demote_ok(gl))
@@ -2018,7 +1965,7 @@ static void scan_glock(struct gfs2_glock *gl)
2018 if (gfs2_glmutex_trylock(gl)) { 1965 if (gfs2_glmutex_trylock(gl)) {
2019 if (gl->gl_ops == &gfs2_inode_glops) { 1966 if (gl->gl_ops == &gfs2_inode_glops) {
2020 struct gfs2_inode *ip = gl->gl_object; 1967 struct gfs2_inode *ip = gl->gl_object;
2021 if (ip && !atomic_read(&ip->i_count)) 1968 if (ip)
2022 goto out_schedule; 1969 goto out_schedule;
2023 } 1970 }
2024 if (queue_empty(gl, &gl->gl_holders) && 1971 if (queue_empty(gl, &gl->gl_holders) &&
@@ -2078,11 +2025,6 @@ static void clear_glock(struct gfs2_glock *gl)
2078 } 2025 }
2079 2026
2080 if (gfs2_glmutex_trylock(gl)) { 2027 if (gfs2_glmutex_trylock(gl)) {
2081 if (gl->gl_ops == &gfs2_inode_glops) {
2082 struct gfs2_inode *ip = gl->gl_object;
2083 if (ip && !atomic_read(&ip->i_count))
2084 gfs2_inode_destroy(ip, 1);
2085 }
2086 if (queue_empty(gl, &gl->gl_holders) && 2028 if (queue_empty(gl, &gl->gl_holders) &&
2087 gl->gl_state != LM_ST_UNLOCKED) 2029 gl->gl_state != LM_ST_UNLOCKED)
2088 handle_callback(gl, LM_ST_UNLOCKED); 2030 handle_callback(gl, LM_ST_UNLOCKED);
@@ -2199,13 +2141,11 @@ static int dump_inode(struct gfs2_inode *ip)
2199 (unsigned long long)ip->i_num.no_formal_ino, 2141 (unsigned long long)ip->i_num.no_formal_ino,
2200 (unsigned long long)ip->i_num.no_addr); 2142 (unsigned long long)ip->i_num.no_addr);
2201 printk(KERN_INFO " type = %u\n", IF2DT(ip->i_di.di_mode)); 2143 printk(KERN_INFO " type = %u\n", IF2DT(ip->i_di.di_mode));
2202 printk(KERN_INFO " i_count = %d\n", atomic_read(&ip->i_count));
2203 printk(KERN_INFO " i_flags ="); 2144 printk(KERN_INFO " i_flags =");
2204 for (x = 0; x < 32; x++) 2145 for (x = 0; x < 32; x++)
2205 if (test_bit(x, &ip->i_flags)) 2146 if (test_bit(x, &ip->i_flags))
2206 printk(" %u", x); 2147 printk(" %u", x);
2207 printk(" \n"); 2148 printk(" \n");
2208 printk(KERN_INFO " vnode = %s\n", (ip->i_vnode) ? "yes" : "no");
2209 2149
2210 error = 0; 2150 error = 0;
2211 2151