1  /*
2   * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3   */
4  
5  #include <linux/string.h>
6  #include <linux/errno.h>
7  #include <linux/fs.h>
8  #include "reiserfs.h"
9  #include <linux/stat.h>
10  #include <linux/buffer_head.h>
11  #include <linux/slab.h>
12  #include <linux/uaccess.h>
13  
14  extern const struct reiserfs_key MIN_KEY;
15  
16  static int reiserfs_readdir(struct file *, struct dir_context *);
17  static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
18  			      int datasync);
19  
20  const struct file_operations reiserfs_dir_operations = {
21  	.llseek = generic_file_llseek,
22  	.read = generic_read_dir,
23  	.iterate_shared = reiserfs_readdir,
24  	.fsync = reiserfs_dir_fsync,
25  	.unlocked_ioctl = reiserfs_ioctl,
26  #ifdef CONFIG_COMPAT
27  	.compat_ioctl = reiserfs_compat_ioctl,
28  #endif
29  };
30  
reiserfs_dir_fsync(struct file * filp,loff_t start,loff_t end,int datasync)31  static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
32  			      int datasync)
33  {
34  	struct inode *inode = filp->f_mapping->host;
35  	int err;
36  
37  	err = file_write_and_wait_range(filp, start, end);
38  	if (err)
39  		return err;
40  
41  	inode_lock(inode);
42  	reiserfs_write_lock(inode->i_sb);
43  	err = reiserfs_commit_for_inode(inode);
44  	reiserfs_write_unlock(inode->i_sb);
45  	inode_unlock(inode);
46  	if (err < 0)
47  		return err;
48  	return 0;
49  }
50  
51  #define store_ih(where,what) copy_item_head (where, what)
52  
is_privroot_deh(struct inode * dir,struct reiserfs_de_head * deh)53  static inline bool is_privroot_deh(struct inode *dir, struct reiserfs_de_head *deh)
54  {
55  	struct dentry *privroot = REISERFS_SB(dir->i_sb)->priv_root;
56  	return (d_really_is_positive(privroot) &&
57  	        deh->deh_objectid == INODE_PKEY(d_inode(privroot))->k_objectid);
58  }
59  
reiserfs_readdir_inode(struct inode * inode,struct dir_context * ctx)60  int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
61  {
62  
63  	/* key of current position in the directory (key of directory entry) */
64  	struct cpu_key pos_key;
65  
66  	INITIALIZE_PATH(path_to_entry);
67  	struct buffer_head *bh;
68  	int item_num, entry_num;
69  	const struct reiserfs_key *rkey;
70  	struct item_head *ih, tmp_ih;
71  	int search_res;
72  	char *local_buf;
73  	loff_t next_pos;
74  	char small_buf[32];	/* avoid kmalloc if we can */
75  	struct reiserfs_dir_entry de;
76  	int ret = 0;
77  	int depth;
78  
79  	reiserfs_write_lock(inode->i_sb);
80  
81  	reiserfs_check_lock_depth(inode->i_sb, "readdir");
82  
83  	/*
84  	 * form key for search the next directory entry using
85  	 * f_pos field of file structure
86  	 */
87  	make_cpu_key(&pos_key, inode, ctx->pos ?: DOT_OFFSET, TYPE_DIRENTRY, 3);
88  	next_pos = cpu_key_k_offset(&pos_key);
89  
90  	path_to_entry.reada = PATH_READA;
91  	while (1) {
92  research:
93  		/*
94  		 * search the directory item, containing entry with
95  		 * specified key
96  		 */
97  		search_res =
98  		    search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry,
99  					&de);
100  		if (search_res == IO_ERROR) {
101  			/*
102  			 * FIXME: we could just skip part of directory
103  			 * which could not be read
104  			 */
105  			ret = -EIO;
106  			goto out;
107  		}
108  		entry_num = de.de_entry_num;
109  		bh = de.de_bh;
110  		item_num = de.de_item_num;
111  		ih = de.de_ih;
112  		store_ih(&tmp_ih, ih);
113  
114  		/* we must have found item, that is item of this directory, */
115  		RFALSE(COMP_SHORT_KEYS(&ih->ih_key, &pos_key),
116  		       "vs-9000: found item %h does not match to dir we readdir %K",
117  		       ih, &pos_key);
118  		RFALSE(item_num > B_NR_ITEMS(bh) - 1,
119  		       "vs-9005 item_num == %d, item amount == %d",
120  		       item_num, B_NR_ITEMS(bh));
121  
122  		/*
123  		 * and entry must be not more than number of entries
124  		 * in the item
125  		 */
126  		RFALSE(ih_entry_count(ih) < entry_num,
127  		       "vs-9010: entry number is too big %d (%d)",
128  		       entry_num, ih_entry_count(ih));
129  
130  		/*
131  		 * go through all entries in the directory item beginning
132  		 * from the entry, that has been found
133  		 */
134  		if (search_res == POSITION_FOUND
135  		    || entry_num < ih_entry_count(ih)) {
136  			struct reiserfs_de_head *deh =
137  			    B_I_DEH(bh, ih) + entry_num;
138  
139  			for (; entry_num < ih_entry_count(ih);
140  			     entry_num++, deh++) {
141  				int d_reclen;
142  				char *d_name;
143  				ino_t d_ino;
144  				loff_t cur_pos = deh_offset(deh);
145  
146  				/* it is hidden entry */
147  				if (!de_visible(deh))
148  					continue;
149  				d_reclen = entry_length(bh, ih, entry_num);
150  				d_name = B_I_DEH_ENTRY_FILE_NAME(bh, ih, deh);
151  
152  				if (d_reclen <= 0 ||
153  				    d_name + d_reclen > bh->b_data + bh->b_size) {
154  					/*
155  					 * There is corrupted data in entry,
156  					 * We'd better stop here
157  					 */
158  					pathrelse(&path_to_entry);
159  					ret = -EIO;
160  					goto out;
161  				}
162  
163  				if (!d_name[d_reclen - 1])
164  					d_reclen = strlen(d_name);
165  
166  				/* too big to send back to VFS */
167  				if (d_reclen >
168  				    REISERFS_MAX_NAME(inode->i_sb->
169  						      s_blocksize)) {
170  					continue;
171  				}
172  
173  				/* Ignore the .reiserfs_priv entry */
174  				if (is_privroot_deh(inode, deh))
175  					continue;
176  
177  				ctx->pos = deh_offset(deh);
178  				d_ino = deh_objectid(deh);
179  				if (d_reclen <= 32) {
180  					local_buf = small_buf;
181  				} else {
182  					local_buf = kmalloc(d_reclen,
183  							    GFP_NOFS);
184  					if (!local_buf) {
185  						pathrelse(&path_to_entry);
186  						ret = -ENOMEM;
187  						goto out;
188  					}
189  					if (item_moved(&tmp_ih, &path_to_entry)) {
190  						kfree(local_buf);
191  						goto research;
192  					}
193  				}
194  
195  				/*
196  				 * Note, that we copy name to user space via
197  				 * temporary buffer (local_buf) because
198  				 * filldir will block if user space buffer is
199  				 * swapped out. At that time entry can move to
200  				 * somewhere else
201  				 */
202  				memcpy(local_buf, d_name, d_reclen);
203  
204  				/*
205  				 * Since filldir might sleep, we can release
206  				 * the write lock here for other waiters
207  				 */
208  				depth = reiserfs_write_unlock_nested(inode->i_sb);
209  				if (!dir_emit
210  				    (ctx, local_buf, d_reclen, d_ino,
211  				     DT_UNKNOWN)) {
212  					reiserfs_write_lock_nested(inode->i_sb, depth);
213  					if (local_buf != small_buf) {
214  						kfree(local_buf);
215  					}
216  					goto end;
217  				}
218  				reiserfs_write_lock_nested(inode->i_sb, depth);
219  				if (local_buf != small_buf) {
220  					kfree(local_buf);
221  				}
222  
223  				/* deh_offset(deh) may be invalid now. */
224  				next_pos = cur_pos + 1;
225  
226  				if (item_moved(&tmp_ih, &path_to_entry)) {
227  					set_cpu_key_k_offset(&pos_key,
228  							     next_pos);
229  					goto research;
230  				}
231  			}	/* for */
232  		}
233  
234  		/* end of directory has been reached */
235  		if (item_num != B_NR_ITEMS(bh) - 1)
236  			goto end;
237  
238  		/*
239  		 * item we went through is last item of node. Using right
240  		 * delimiting key check is it directory end
241  		 */
242  		rkey = get_rkey(&path_to_entry, inode->i_sb);
243  		if (!comp_le_keys(rkey, &MIN_KEY)) {
244  			/*
245  			 * set pos_key to key, that is the smallest and greater
246  			 * that key of the last entry in the item
247  			 */
248  			set_cpu_key_k_offset(&pos_key, next_pos);
249  			continue;
250  		}
251  
252  		/* end of directory has been reached */
253  		if (COMP_SHORT_KEYS(rkey, &pos_key)) {
254  			goto end;
255  		}
256  
257  		/* directory continues in the right neighboring block */
258  		set_cpu_key_k_offset(&pos_key,
259  				     le_key_k_offset(KEY_FORMAT_3_5, rkey));
260  
261  	}			/* while */
262  
263  end:
264  	ctx->pos = next_pos;
265  	pathrelse(&path_to_entry);
266  	reiserfs_check_path(&path_to_entry);
267  out:
268  	reiserfs_write_unlock(inode->i_sb);
269  	return ret;
270  }
271  
reiserfs_readdir(struct file * file,struct dir_context * ctx)272  static int reiserfs_readdir(struct file *file, struct dir_context *ctx)
273  {
274  	return reiserfs_readdir_inode(file_inode(file), ctx);
275  }
276  
277  /*
278   * compose directory item containing "." and ".." entries (entries are
279   * not aligned to 4 byte boundary)
280   */
make_empty_dir_item_v1(char * body,__le32 dirid,__le32 objid,__le32 par_dirid,__le32 par_objid)281  void make_empty_dir_item_v1(char *body, __le32 dirid, __le32 objid,
282  			    __le32 par_dirid, __le32 par_objid)
283  {
284  	struct reiserfs_de_head *dot, *dotdot;
285  
286  	memset(body, 0, EMPTY_DIR_SIZE_V1);
287  	dot = (struct reiserfs_de_head *)body;
288  	dotdot = dot + 1;
289  
290  	/* direntry header of "." */
291  	put_deh_offset(dot, DOT_OFFSET);
292  	/* these two are from make_le_item_head, and are LE */
293  	dot->deh_dir_id = dirid;
294  	dot->deh_objectid = objid;
295  	dot->deh_state = 0;	/* Endian safe if 0 */
296  	put_deh_location(dot, EMPTY_DIR_SIZE_V1 - strlen("."));
297  	mark_de_visible(dot);
298  
299  	/* direntry header of ".." */
300  	put_deh_offset(dotdot, DOT_DOT_OFFSET);
301  	/* key of ".." for the root directory */
302  	/* these two are from the inode, and are LE */
303  	dotdot->deh_dir_id = par_dirid;
304  	dotdot->deh_objectid = par_objid;
305  	dotdot->deh_state = 0;	/* Endian safe if 0 */
306  	put_deh_location(dotdot, deh_location(dot) - strlen(".."));
307  	mark_de_visible(dotdot);
308  
309  	/* copy ".." and "." */
310  	memcpy(body + deh_location(dot), ".", 1);
311  	memcpy(body + deh_location(dotdot), "..", 2);
312  }
313  
314  /* compose directory item containing "." and ".." entries */
make_empty_dir_item(char * body,__le32 dirid,__le32 objid,__le32 par_dirid,__le32 par_objid)315  void make_empty_dir_item(char *body, __le32 dirid, __le32 objid,
316  			 __le32 par_dirid, __le32 par_objid)
317  {
318  	struct reiserfs_de_head *dot, *dotdot;
319  
320  	memset(body, 0, EMPTY_DIR_SIZE);
321  	dot = (struct reiserfs_de_head *)body;
322  	dotdot = dot + 1;
323  
324  	/* direntry header of "." */
325  	put_deh_offset(dot, DOT_OFFSET);
326  	/* these two are from make_le_item_head, and are LE */
327  	dot->deh_dir_id = dirid;
328  	dot->deh_objectid = objid;
329  	dot->deh_state = 0;	/* Endian safe if 0 */
330  	put_deh_location(dot, EMPTY_DIR_SIZE - ROUND_UP(strlen(".")));
331  	mark_de_visible(dot);
332  
333  	/* direntry header of ".." */
334  	put_deh_offset(dotdot, DOT_DOT_OFFSET);
335  	/* key of ".." for the root directory */
336  	/* these two are from the inode, and are LE */
337  	dotdot->deh_dir_id = par_dirid;
338  	dotdot->deh_objectid = par_objid;
339  	dotdot->deh_state = 0;	/* Endian safe if 0 */
340  	put_deh_location(dotdot, deh_location(dot) - ROUND_UP(strlen("..")));
341  	mark_de_visible(dotdot);
342  
343  	/* copy ".." and "." */
344  	memcpy(body + deh_location(dot), ".", 1);
345  	memcpy(body + deh_location(dotdot), "..", 2);
346  }
347