aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.com>2010-08-13 18:15:18 -0400
committerTao Ma <tao.ma@oracle.com>2010-09-08 02:26:00 -0400
commitdd43bcde23c527f64897eef41aa1fed2c9905ea9 (patch)
tree59a35711f0d21ef5198b6721e97a622b3e5f384d /fs
parente49e27674d1dd2717ad90b21ece8f83102153315 (diff)
ocfs2: split out ocfs2_prepare_orphan_dir() into locking and prep functions
We do this because ocfs2_create_inode_in_orphan() wants to order locking of the orphan dir with respect to locking of the inode allocator *before* making any changes to the directory. Signed-off-by: Mark Fasheh <mfasheh@suse.com> Signed-off-by: Tao Ma <tao.ma@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/namei.c120
1 files changed, 88 insertions, 32 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 2aa66b695fab..54c629855357 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1871,61 +1871,117 @@ bail:
1871 return status; 1871 return status;
1872} 1872}
1873 1873
1874static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, 1874static int ocfs2_lookup_lock_orphan_dir(struct ocfs2_super *osb,
1875 struct inode **ret_orphan_dir, 1875 struct inode **ret_orphan_dir,
1876 u64 blkno, 1876 struct buffer_head **ret_orphan_dir_bh)
1877 char *name,
1878 struct ocfs2_dir_lookup_result *lookup)
1879{ 1877{
1880 struct inode *orphan_dir_inode; 1878 struct inode *orphan_dir_inode;
1881 struct buffer_head *orphan_dir_bh = NULL; 1879 struct buffer_head *orphan_dir_bh = NULL;
1882 int status = 0; 1880 int ret = 0;
1883
1884 status = ocfs2_blkno_stringify(blkno, name);
1885 if (status < 0) {
1886 mlog_errno(status);
1887 return status;
1888 }
1889 1881
1890 orphan_dir_inode = ocfs2_get_system_file_inode(osb, 1882 orphan_dir_inode = ocfs2_get_system_file_inode(osb,
1891 ORPHAN_DIR_SYSTEM_INODE, 1883 ORPHAN_DIR_SYSTEM_INODE,
1892 osb->slot_num); 1884 osb->slot_num);
1893 if (!orphan_dir_inode) { 1885 if (!orphan_dir_inode) {
1894 status = -ENOENT; 1886 ret = -ENOENT;
1895 mlog_errno(status); 1887 mlog_errno(ret);
1896 return status; 1888 return ret;
1897 } 1889 }
1898 1890
1899 mutex_lock(&orphan_dir_inode->i_mutex); 1891 mutex_lock(&orphan_dir_inode->i_mutex);
1900 1892
1901 status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); 1893 ret = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
1902 if (status < 0) { 1894 if (ret < 0) {
1903 mlog_errno(status); 1895 mutex_unlock(&orphan_dir_inode->i_mutex);
1904 goto leave; 1896 iput(orphan_dir_inode);
1897
1898 mlog_errno(ret);
1899 return ret;
1905 } 1900 }
1906 1901
1907 status = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode, 1902 *ret_orphan_dir = orphan_dir_inode;
1908 orphan_dir_bh, name, 1903 *ret_orphan_dir_bh = orphan_dir_bh;
1909 OCFS2_ORPHAN_NAMELEN, lookup);
1910 if (status < 0) {
1911 ocfs2_inode_unlock(orphan_dir_inode, 1);
1912 1904
1913 mlog_errno(status); 1905 return 0;
1914 goto leave; 1906}
1907
1908static int __ocfs2_prepare_orphan_dir(struct inode *orphan_dir_inode,
1909 struct buffer_head *orphan_dir_bh,
1910 u64 blkno,
1911 char *name,
1912 struct ocfs2_dir_lookup_result *lookup)
1913{
1914 int ret;
1915 struct ocfs2_super *osb = OCFS2_SB(orphan_dir_inode->i_sb);
1916
1917 ret = ocfs2_blkno_stringify(blkno, name);
1918 if (ret < 0) {
1919 mlog_errno(ret);
1920 return ret;
1921 }
1922
1923 ret = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode,
1924 orphan_dir_bh, name,
1925 OCFS2_ORPHAN_NAMELEN, lookup);
1926 if (ret < 0) {
1927 mlog_errno(ret);
1928 return ret;
1929 }
1930
1931 return 0;
1932}
1933
1934/**
1935 * ocfs2_prepare_orphan_dir() - Prepare an orphan directory for
1936 * insertion of an orphan.
1937 * @osb: ocfs2 file system
1938 * @ret_orphan_dir: Orphan dir inode - returned locked!
1939 * @blkno: Actual block number of the inode to be inserted into orphan dir.
1940 * @lookup: dir lookup result, to be passed back into functions like
1941 * ocfs2_orphan_add
1942 *
1943 * Returns zero on success and the ret_orphan_dir, name and lookup
1944 * fields will be populated.
1945 *
1946 * Returns non-zero on failure.
1947 */
1948static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
1949 struct inode **ret_orphan_dir,
1950 u64 blkno,
1951 char *name,
1952 struct ocfs2_dir_lookup_result *lookup)
1953{
1954 struct inode *orphan_dir_inode = NULL;
1955 struct buffer_head *orphan_dir_bh = NULL;
1956 int ret = 0;
1957
1958 ret = ocfs2_lookup_lock_orphan_dir(osb, &orphan_dir_inode,
1959 &orphan_dir_bh);
1960 if (ret < 0) {
1961 mlog_errno(ret);
1962 return ret;
1963 }
1964
1965 ret = __ocfs2_prepare_orphan_dir(orphan_dir_inode, orphan_dir_bh,
1966 blkno, name, lookup);
1967 if (ret < 0) {
1968 mlog_errno(ret);
1969 goto out;
1915 } 1970 }
1916 1971
1917 *ret_orphan_dir = orphan_dir_inode; 1972 *ret_orphan_dir = orphan_dir_inode;
1918 1973
1919leave: 1974out:
1920 if (status) { 1975 brelse(orphan_dir_bh);
1976
1977 if (ret) {
1978 ocfs2_inode_unlock(orphan_dir_inode, 1);
1921 mutex_unlock(&orphan_dir_inode->i_mutex); 1979 mutex_unlock(&orphan_dir_inode->i_mutex);
1922 iput(orphan_dir_inode); 1980 iput(orphan_dir_inode);
1923 } 1981 }
1924 1982
1925 brelse(orphan_dir_bh); 1983 mlog_exit(ret);
1926 1984 return ret;
1927 mlog_exit(status);
1928 return status;
1929} 1985}
1930 1986
1931static int ocfs2_orphan_add(struct ocfs2_super *osb, 1987static int ocfs2_orphan_add(struct ocfs2_super *osb,