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, |
