diff options
-rw-r--r-- | fs/ocfs2/namei.c | 120 |
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 | ||
1874 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 1874 | static 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 | |||
1908 | static 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 | */ | ||
1948 | static 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 | ||
1919 | leave: | 1974 | out: |
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 | ||
1931 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 1987 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |