aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/namei.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-09-07 21:21:26 -0400
committerMark Fasheh <mark.fasheh@oracle.com>2007-10-12 14:54:36 -0400
commit316f4b9f98a353ac1be93199694fd97272378815 (patch)
treec54f7feb08fc1693f64879d8a3edc18cf3bb2713 /fs/ocfs2/namei.c
parent1d410a6e337a0d2d5543ad1d9bccb670a7a05312 (diff)
ocfs2: Move directory manipulation code into dir.c
The code for adding, removing, deleting directory entries was splattered all over namei.c. I'd rather have this all centralized, so that it's easier to make changes for inline dir data, and eventually indexed directories. None of the code in any of the functions was changed. I only removed the static keyword from some prototypes so that they could be exported. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com> Reviewed-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r--fs/ocfs2/namei.c433
1 files changed, 0 insertions, 433 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 701e6d04ed5d..aae6c0bf6696 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -64,29 +64,6 @@
64 64
65#include "buffer_head_io.h" 65#include "buffer_head_io.h"
66 66
67#define NAMEI_RA_CHUNKS 2
68#define NAMEI_RA_BLOCKS 4
69#define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
70#define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b))
71
72static int inline ocfs2_search_dirblock(struct buffer_head *bh,
73 struct inode *dir,
74 const char *name, int namelen,
75 unsigned long offset,
76 struct ocfs2_dir_entry **res_dir);
77
78static int ocfs2_delete_entry(handle_t *handle,
79 struct inode *dir,
80 struct ocfs2_dir_entry *de_del,
81 struct buffer_head *bh);
82
83static int __ocfs2_add_entry(handle_t *handle,
84 struct inode *dir,
85 const char *name, int namelen,
86 struct inode *inode, u64 blkno,
87 struct buffer_head *parent_fe_bh,
88 struct buffer_head *insert_bh);
89
90static int ocfs2_mknod_locked(struct ocfs2_super *osb, 67static int ocfs2_mknod_locked(struct ocfs2_super *osb,
91 struct inode *dir, 68 struct inode *dir,
92 struct dentry *dentry, int mode, 69 struct dentry *dentry, int mode,
@@ -97,13 +74,6 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
97 struct inode **ret_inode, 74 struct inode **ret_inode,
98 struct ocfs2_alloc_context *inode_ac); 75 struct ocfs2_alloc_context *inode_ac);
99 76
100static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
101 handle_t *handle,
102 struct inode *parent,
103 struct inode *inode,
104 struct buffer_head *fe_bh,
105 struct ocfs2_alloc_context *data_ac);
106
107static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, 77static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
108 struct inode **ret_orphan_dir, 78 struct inode **ret_orphan_dir,
109 struct inode *inode, 79 struct inode *inode,
@@ -123,17 +93,6 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
123 struct inode *inode, 93 struct inode *inode,
124 const char *symname); 94 const char *symname);
125 95
126static inline int ocfs2_add_entry(handle_t *handle,
127 struct dentry *dentry,
128 struct inode *inode, u64 blkno,
129 struct buffer_head *parent_fe_bh,
130 struct buffer_head *insert_bh)
131{
132 return __ocfs2_add_entry(handle, dentry->d_parent->d_inode,
133 dentry->d_name.name, dentry->d_name.len,
134 inode, blkno, parent_fe_bh, insert_bh);
135}
136
137/* An orphan dir name is an 8 byte value, printed as a hex string */ 96/* An orphan dir name is an 8 byte value, printed as a hex string */
138#define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64))) 97#define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
139 98
@@ -232,75 +191,6 @@ bail:
232 return ret; 191 return ret;
233} 192}
234 193
235static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
236 handle_t *handle,
237 struct inode *parent,
238 struct inode *inode,
239 struct buffer_head *fe_bh,
240 struct ocfs2_alloc_context *data_ac)
241{
242 int status;
243 struct buffer_head *new_bh = NULL;
244 struct ocfs2_dir_entry *de = NULL;
245
246 mlog_entry_void();
247
248 status = ocfs2_do_extend_dir(osb->sb, handle, inode, fe_bh,
249 data_ac, NULL, &new_bh);
250 if (status < 0) {
251 mlog_errno(status);
252 goto bail;
253 }
254
255 ocfs2_set_new_buffer_uptodate(inode, new_bh);
256
257 status = ocfs2_journal_access(handle, inode, new_bh,
258 OCFS2_JOURNAL_ACCESS_CREATE);
259 if (status < 0) {
260 mlog_errno(status);
261 goto bail;
262 }
263 memset(new_bh->b_data, 0, osb->sb->s_blocksize);
264
265 de = (struct ocfs2_dir_entry *) new_bh->b_data;
266 de->inode = cpu_to_le64(OCFS2_I(inode)->ip_blkno);
267 de->name_len = 1;
268 de->rec_len =
269 cpu_to_le16(OCFS2_DIR_REC_LEN(de->name_len));
270 strcpy(de->name, ".");
271 ocfs2_set_de_type(de, S_IFDIR);
272 de = (struct ocfs2_dir_entry *) ((char *)de + le16_to_cpu(de->rec_len));
273 de->inode = cpu_to_le64(OCFS2_I(parent)->ip_blkno);
274 de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize -
275 OCFS2_DIR_REC_LEN(1));
276 de->name_len = 2;
277 strcpy(de->name, "..");
278 ocfs2_set_de_type(de, S_IFDIR);
279
280 status = ocfs2_journal_dirty(handle, new_bh);
281 if (status < 0) {
282 mlog_errno(status);
283 goto bail;
284 }
285
286 i_size_write(inode, inode->i_sb->s_blocksize);
287 inode->i_nlink = 2;
288 inode->i_blocks = ocfs2_inode_sector_count(inode);
289 status = ocfs2_mark_inode_dirty(handle, inode, fe_bh);
290 if (status < 0) {
291 mlog_errno(status);
292 goto bail;
293 }
294
295 status = 0;
296bail:
297 if (new_bh)
298 brelse(new_bh);
299
300 mlog_exit(status);
301 return status;
302}
303
304static int ocfs2_mknod(struct inode *dir, 194static int ocfs2_mknod(struct inode *dir,
305 struct dentry *dentry, 195 struct dentry *dentry,
306 int mode, 196 int mode,
@@ -1767,329 +1657,6 @@ bail:
1767 return status; 1657 return status;
1768} 1658}
1769 1659
1770int ocfs2_check_dir_entry(struct inode * dir,
1771 struct ocfs2_dir_entry * de,
1772 struct buffer_head * bh,
1773 unsigned long offset)
1774{
1775 const char *error_msg = NULL;
1776 const int rlen = le16_to_cpu(de->rec_len);
1777
1778 if (rlen < OCFS2_DIR_REC_LEN(1))
1779 error_msg = "rec_len is smaller than minimal";
1780 else if (rlen % 4 != 0)
1781 error_msg = "rec_len % 4 != 0";
1782 else if (rlen < OCFS2_DIR_REC_LEN(de->name_len))
1783 error_msg = "rec_len is too small for name_len";
1784 else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
1785 error_msg = "directory entry across blocks";
1786
1787 if (error_msg != NULL)
1788 mlog(ML_ERROR, "bad entry in directory #%llu: %s - "
1789 "offset=%lu, inode=%llu, rec_len=%d, name_len=%d\n",
1790 (unsigned long long)OCFS2_I(dir)->ip_blkno, error_msg,
1791 offset, (unsigned long long)le64_to_cpu(de->inode), rlen,
1792 de->name_len);
1793 return error_msg == NULL ? 1 : 0;
1794}
1795
1796/* we don't always have a dentry for what we want to add, so people
1797 * like orphan dir can call this instead.
1798 *
1799 * If you pass me insert_bh, I'll skip the search of the other dir
1800 * blocks and put the record in there.
1801 */
1802static int __ocfs2_add_entry(handle_t *handle,
1803 struct inode *dir,
1804 const char *name, int namelen,
1805 struct inode *inode, u64 blkno,
1806 struct buffer_head *parent_fe_bh,
1807 struct buffer_head *insert_bh)
1808{
1809 unsigned long offset;
1810 unsigned short rec_len;
1811 struct ocfs2_dir_entry *de, *de1;
1812 struct super_block *sb;
1813 int retval, status;
1814
1815 mlog_entry_void();
1816
1817 sb = dir->i_sb;
1818
1819 if (!namelen)
1820 return -EINVAL;
1821
1822 rec_len = OCFS2_DIR_REC_LEN(namelen);
1823 offset = 0;
1824 de = (struct ocfs2_dir_entry *) insert_bh->b_data;
1825 while (1) {
1826 BUG_ON((char *)de >= sb->s_blocksize + insert_bh->b_data);
1827 /* These checks should've already been passed by the
1828 * prepare function, but I guess we can leave them
1829 * here anyway. */
1830 if (!ocfs2_check_dir_entry(dir, de, insert_bh, offset)) {
1831 retval = -ENOENT;
1832 goto bail;
1833 }
1834 if (ocfs2_match(namelen, name, de)) {
1835 retval = -EEXIST;
1836 goto bail;
1837 }
1838 if (((le64_to_cpu(de->inode) == 0) &&
1839 (le16_to_cpu(de->rec_len) >= rec_len)) ||
1840 (le16_to_cpu(de->rec_len) >=
1841 (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) {
1842 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
1843 retval = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh);
1844 if (retval < 0) {
1845 mlog_errno(retval);
1846 goto bail;
1847 }
1848
1849 status = ocfs2_journal_access(handle, dir, insert_bh,
1850 OCFS2_JOURNAL_ACCESS_WRITE);
1851 /* By now the buffer is marked for journaling */
1852 offset += le16_to_cpu(de->rec_len);
1853 if (le64_to_cpu(de->inode)) {
1854 de1 = (struct ocfs2_dir_entry *)((char *) de +
1855 OCFS2_DIR_REC_LEN(de->name_len));
1856 de1->rec_len =
1857 cpu_to_le16(le16_to_cpu(de->rec_len) -
1858 OCFS2_DIR_REC_LEN(de->name_len));
1859 de->rec_len = cpu_to_le16(OCFS2_DIR_REC_LEN(de->name_len));
1860 de = de1;
1861 }
1862 de->file_type = OCFS2_FT_UNKNOWN;
1863 if (blkno) {
1864 de->inode = cpu_to_le64(blkno);
1865 ocfs2_set_de_type(de, inode->i_mode);
1866 } else
1867 de->inode = 0;
1868 de->name_len = namelen;
1869 memcpy(de->name, name, namelen);
1870
1871 dir->i_version++;
1872 status = ocfs2_journal_dirty(handle, insert_bh);
1873 retval = 0;
1874 goto bail;
1875 }
1876 offset += le16_to_cpu(de->rec_len);
1877 de = (struct ocfs2_dir_entry *) ((char *) de + le16_to_cpu(de->rec_len));
1878 }
1879
1880 /* when you think about it, the assert above should prevent us
1881 * from ever getting here. */
1882 retval = -ENOSPC;
1883bail:
1884
1885 mlog_exit(retval);
1886 return retval;
1887}
1888
1889
1890/*
1891 * ocfs2_delete_entry deletes a directory entry by merging it with the
1892 * previous entry
1893 */
1894static int ocfs2_delete_entry(handle_t *handle,
1895 struct inode *dir,
1896 struct ocfs2_dir_entry *de_del,
1897 struct buffer_head *bh)
1898{
1899 struct ocfs2_dir_entry *de, *pde;
1900 int i, status = -ENOENT;
1901
1902 mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p)\n", handle, dir, de_del, bh);
1903
1904 i = 0;
1905 pde = NULL;
1906 de = (struct ocfs2_dir_entry *) bh->b_data;
1907 while (i < bh->b_size) {
1908 if (!ocfs2_check_dir_entry(dir, de, bh, i)) {
1909 status = -EIO;
1910 mlog_errno(status);
1911 goto bail;
1912 }
1913 if (de == de_del) {
1914 status = ocfs2_journal_access(handle, dir, bh,
1915 OCFS2_JOURNAL_ACCESS_WRITE);
1916 if (status < 0) {
1917 status = -EIO;
1918 mlog_errno(status);
1919 goto bail;
1920 }
1921 if (pde)
1922 pde->rec_len =
1923 cpu_to_le16(le16_to_cpu(pde->rec_len) +
1924 le16_to_cpu(de->rec_len));
1925 else
1926 de->inode = 0;
1927 dir->i_version++;
1928 status = ocfs2_journal_dirty(handle, bh);
1929 goto bail;
1930 }
1931 i += le16_to_cpu(de->rec_len);
1932 pde = de;
1933 de = (struct ocfs2_dir_entry *)((char *)de + le16_to_cpu(de->rec_len));
1934 }
1935bail:
1936 mlog_exit(status);
1937 return status;
1938}
1939
1940/*
1941 * Returns 0 if not found, -1 on failure, and 1 on success
1942 */
1943static int inline ocfs2_search_dirblock(struct buffer_head *bh,
1944 struct inode *dir,
1945 const char *name, int namelen,
1946 unsigned long offset,
1947 struct ocfs2_dir_entry **res_dir)
1948{
1949 struct ocfs2_dir_entry *de;
1950 char *dlimit, *de_buf;
1951 int de_len;
1952 int ret = 0;
1953
1954 mlog_entry_void();
1955
1956 de_buf = bh->b_data;
1957 dlimit = de_buf + dir->i_sb->s_blocksize;
1958
1959 while (de_buf < dlimit) {
1960 /* this code is executed quadratically often */
1961 /* do minimal checking `by hand' */
1962
1963 de = (struct ocfs2_dir_entry *) de_buf;
1964
1965 if (de_buf + namelen <= dlimit &&
1966 ocfs2_match(namelen, name, de)) {
1967 /* found a match - just to be sure, do a full check */
1968 if (!ocfs2_check_dir_entry(dir, de, bh, offset)) {
1969 ret = -1;
1970 goto bail;
1971 }
1972 *res_dir = de;
1973 ret = 1;
1974 goto bail;
1975 }
1976
1977 /* prevent looping on a bad block */
1978 de_len = le16_to_cpu(de->rec_len);
1979 if (de_len <= 0) {
1980 ret = -1;
1981 goto bail;
1982 }
1983
1984 de_buf += de_len;
1985 offset += de_len;
1986 }
1987
1988bail:
1989 mlog_exit(ret);
1990 return ret;
1991}
1992
1993struct buffer_head *ocfs2_find_entry(const char *name, int namelen,
1994 struct inode *dir,
1995 struct ocfs2_dir_entry **res_dir)
1996{
1997 struct super_block *sb;
1998 struct buffer_head *bh_use[NAMEI_RA_SIZE];
1999 struct buffer_head *bh, *ret = NULL;
2000 unsigned long start, block, b;
2001 int ra_max = 0; /* Number of bh's in the readahead
2002 buffer, bh_use[] */
2003 int ra_ptr = 0; /* Current index into readahead
2004 buffer */
2005 int num = 0;
2006 int nblocks, i, err;
2007
2008 mlog_entry_void();
2009
2010 *res_dir = NULL;
2011 sb = dir->i_sb;
2012
2013 nblocks = i_size_read(dir) >> sb->s_blocksize_bits;
2014 start = OCFS2_I(dir)->ip_dir_start_lookup;
2015 if (start >= nblocks)
2016 start = 0;
2017 block = start;
2018
2019restart:
2020 do {
2021 /*
2022 * We deal with the read-ahead logic here.
2023 */
2024 if (ra_ptr >= ra_max) {
2025 /* Refill the readahead buffer */
2026 ra_ptr = 0;
2027 b = block;
2028 for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) {
2029 /*
2030 * Terminate if we reach the end of the
2031 * directory and must wrap, or if our
2032 * search has finished at this block.
2033 */
2034 if (b >= nblocks || (num && block == start)) {
2035 bh_use[ra_max] = NULL;
2036 break;
2037 }
2038 num++;
2039
2040 bh = ocfs2_bread(dir, b++, &err, 1);
2041 bh_use[ra_max] = bh;
2042 }
2043 }
2044 if ((bh = bh_use[ra_ptr++]) == NULL)
2045 goto next;
2046 wait_on_buffer(bh);
2047 if (!buffer_uptodate(bh)) {
2048 /* read error, skip block & hope for the best */
2049 ocfs2_error(dir->i_sb, "reading directory %llu, "
2050 "offset %lu\n",
2051 (unsigned long long)OCFS2_I(dir)->ip_blkno,
2052 block);
2053 brelse(bh);
2054 goto next;
2055 }
2056 i = ocfs2_search_dirblock(bh, dir, name, namelen,
2057 block << sb->s_blocksize_bits,
2058 res_dir);
2059 if (i == 1) {
2060 OCFS2_I(dir)->ip_dir_start_lookup = block;
2061 ret = bh;
2062 goto cleanup_and_exit;
2063 } else {
2064 brelse(bh);
2065 if (i < 0)
2066 goto cleanup_and_exit;
2067 }
2068 next:
2069 if (++block >= nblocks)
2070 block = 0;
2071 } while (block != start);
2072
2073 /*
2074 * If the directory has grown while we were searching, then
2075 * search the last part of the directory before giving up.
2076 */
2077 block = nblocks;
2078 nblocks = i_size_read(dir) >> sb->s_blocksize_bits;
2079 if (block < nblocks) {
2080 start = 0;
2081 goto restart;
2082 }
2083
2084cleanup_and_exit:
2085 /* Clean up the read-ahead blocks */
2086 for (; ra_ptr < ra_max; ra_ptr++)
2087 brelse(bh_use[ra_ptr]);
2088
2089 mlog_exit_ptr(ret);
2090 return ret;
2091}
2092
2093static int ocfs2_blkno_stringify(u64 blkno, char *name) 1660static int ocfs2_blkno_stringify(u64 blkno, char *name)
2094{ 1661{
2095 int status, namelen; 1662 int status, namelen;