2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
5 #include <linux/string.h>
6 #include <linux/errno.h>
8 #include <linux/reiserfs_fs.h>
9 #include <linux/stat.h>
10 #include <linux/smp_lock.h>
11 #include <linux/buffer_head.h>
12 #include <asm/uaccess.h>
14 extern struct reiserfs_key MIN_KEY
;
16 static int reiserfs_readdir(struct file
*, void *, filldir_t
);
17 static int reiserfs_dir_fsync(struct file
*filp
, struct dentry
*dentry
,
20 const struct file_operations reiserfs_dir_operations
= {
21 .read
= generic_read_dir
,
22 .readdir
= reiserfs_readdir
,
23 .fsync
= reiserfs_dir_fsync
,
24 .ioctl
= reiserfs_ioctl
,
27 static int reiserfs_dir_fsync(struct file
*filp
, struct dentry
*dentry
,
30 struct inode
*inode
= dentry
->d_inode
;
32 reiserfs_write_lock(inode
->i_sb
);
33 err
= reiserfs_commit_for_inode(inode
);
34 reiserfs_write_unlock(inode
->i_sb
);
40 #define store_ih(where,what) copy_item_head (where, what)
43 static int reiserfs_readdir(struct file
*filp
, void *dirent
, filldir_t filldir
)
45 struct inode
*inode
= filp
->f_dentry
->d_inode
;
46 struct cpu_key pos_key
; /* key of current position in the directory (key of directory entry) */
47 INITIALIZE_PATH(path_to_entry
);
48 struct buffer_head
*bh
;
49 int item_num
, entry_num
;
50 const struct reiserfs_key
*rkey
;
51 struct item_head
*ih
, tmp_ih
;
55 char small_buf
[32]; /* avoid kmalloc if we can */
56 struct reiserfs_dir_entry de
;
59 reiserfs_write_lock(inode
->i_sb
);
61 reiserfs_check_lock_depth(inode
->i_sb
, "readdir");
63 /* form key for search the next directory entry using f_pos field of
65 make_cpu_key(&pos_key
, inode
,
66 (filp
->f_pos
) ? (filp
->f_pos
) : DOT_OFFSET
, TYPE_DIRENTRY
,
68 next_pos
= cpu_key_k_offset(&pos_key
);
70 /* reiserfs_warning (inode->i_sb, "reiserfs_readdir 1: f_pos = %Ld", filp->f_pos); */
72 path_to_entry
.reada
= PATH_READA
;
75 /* search the directory item, containing entry with specified key */
77 search_by_entry_key(inode
->i_sb
, &pos_key
, &path_to_entry
,
79 if (search_res
== IO_ERROR
) {
80 // FIXME: we could just skip part of directory which could
85 entry_num
= de
.de_entry_num
;
87 item_num
= de
.de_item_num
;
89 store_ih(&tmp_ih
, ih
);
91 /* we must have found item, that is item of this directory, */
92 RFALSE(COMP_SHORT_KEYS(&(ih
->ih_key
), &pos_key
),
93 "vs-9000: found item %h does not match to dir we readdir %K",
95 RFALSE(item_num
> B_NR_ITEMS(bh
) - 1,
96 "vs-9005 item_num == %d, item amount == %d",
97 item_num
, B_NR_ITEMS(bh
));
99 /* and entry must be not more than number of entries in the item */
100 RFALSE(I_ENTRY_COUNT(ih
) < entry_num
,
101 "vs-9010: entry number is too big %d (%d)",
102 entry_num
, I_ENTRY_COUNT(ih
));
104 if (search_res
== POSITION_FOUND
105 || entry_num
< I_ENTRY_COUNT(ih
)) {
106 /* go through all entries in the directory item beginning from the entry, that has been found */
107 struct reiserfs_de_head
*deh
=
108 B_I_DEH(bh
, ih
) + entry_num
;
110 for (; entry_num
< I_ENTRY_COUNT(ih
);
111 entry_num
++, deh
++) {
117 if (!de_visible(deh
))
118 /* it is hidden entry */
120 d_reclen
= entry_length(bh
, ih
, entry_num
);
121 d_name
= B_I_DEH_ENTRY_FILE_NAME(bh
, ih
, deh
);
122 if (!d_name
[d_reclen
- 1])
123 d_reclen
= strlen(d_name
);
126 REISERFS_MAX_NAME(inode
->i_sb
->
128 /* too big to send back to VFS */
132 /* Ignore the .reiserfs_priv entry */
133 if (reiserfs_xattrs(inode
->i_sb
) &&
134 !old_format_only(inode
->i_sb
) &&
135 filp
->f_dentry
== inode
->i_sb
->s_root
&&
136 REISERFS_SB(inode
->i_sb
)->priv_root
&&
137 REISERFS_SB(inode
->i_sb
)->priv_root
->d_inode
138 && deh_objectid(deh
) ==
139 le32_to_cpu(INODE_PKEY
140 (REISERFS_SB(inode
->i_sb
)->
141 priv_root
->d_inode
)->
146 d_off
= deh_offset(deh
);
148 d_ino
= deh_objectid(deh
);
149 if (d_reclen
<= 32) {
150 local_buf
= small_buf
;
152 local_buf
= kmalloc(d_reclen
,
155 pathrelse(&path_to_entry
);
159 if (item_moved(&tmp_ih
, &path_to_entry
)) {
164 // Note, that we copy name to user space via temporary
165 // buffer (local_buf) because filldir will block if
166 // user space buffer is swapped out. At that time
167 // entry can move to somewhere else
168 memcpy(local_buf
, d_name
, d_reclen
);
170 (dirent
, local_buf
, d_reclen
, d_off
, d_ino
,
172 if (local_buf
!= small_buf
) {
177 if (local_buf
!= small_buf
) {
180 // next entry should be looked for with such offset
181 next_pos
= deh_offset(deh
) + 1;
183 if (item_moved(&tmp_ih
, &path_to_entry
)) {
189 if (item_num
!= B_NR_ITEMS(bh
) - 1)
190 // end of directory has been reached
193 /* item we went through is last item of node. Using right
194 delimiting key check is it directory end */
195 rkey
= get_rkey(&path_to_entry
, inode
->i_sb
);
196 if (!comp_le_keys(rkey
, &MIN_KEY
)) {
197 /* set pos_key to key, that is the smallest and greater
198 that key of the last entry in the item */
199 set_cpu_key_k_offset(&pos_key
, next_pos
);
203 if (COMP_SHORT_KEYS(rkey
, &pos_key
)) {
204 // end of directory has been reached
208 /* directory continues in the right neighboring block */
209 set_cpu_key_k_offset(&pos_key
,
210 le_key_k_offset(KEY_FORMAT_3_5
, rkey
));
215 filp
->f_pos
= next_pos
;
216 pathrelse(&path_to_entry
);
217 reiserfs_check_path(&path_to_entry
);
219 reiserfs_write_unlock(inode
->i_sb
);
223 /* compose directory item containing "." and ".." entries (entries are
224 not aligned to 4 byte boundary) */
225 /* the last four params are LE */
226 void make_empty_dir_item_v1(char *body
, __le32 dirid
, __le32 objid
,
227 __le32 par_dirid
, __le32 par_objid
)
229 struct reiserfs_de_head
*deh
;
231 memset(body
, 0, EMPTY_DIR_SIZE_V1
);
232 deh
= (struct reiserfs_de_head
*)body
;
234 /* direntry header of "." */
235 put_deh_offset(&(deh
[0]), DOT_OFFSET
);
236 /* these two are from make_le_item_head, and are are LE */
237 deh
[0].deh_dir_id
= dirid
;
238 deh
[0].deh_objectid
= objid
;
239 deh
[0].deh_state
= 0; /* Endian safe if 0 */
240 put_deh_location(&(deh
[0]), EMPTY_DIR_SIZE_V1
- strlen("."));
241 mark_de_visible(&(deh
[0]));
243 /* direntry header of ".." */
244 put_deh_offset(&(deh
[1]), DOT_DOT_OFFSET
);
245 /* key of ".." for the root directory */
246 /* these two are from the inode, and are are LE */
247 deh
[1].deh_dir_id
= par_dirid
;
248 deh
[1].deh_objectid
= par_objid
;
249 deh
[1].deh_state
= 0; /* Endian safe if 0 */
250 put_deh_location(&(deh
[1]), deh_location(&(deh
[0])) - strlen(".."));
251 mark_de_visible(&(deh
[1]));
253 /* copy ".." and "." */
254 memcpy(body
+ deh_location(&(deh
[0])), ".", 1);
255 memcpy(body
+ deh_location(&(deh
[1])), "..", 2);
258 /* compose directory item containing "." and ".." entries */
259 void make_empty_dir_item(char *body
, __le32 dirid
, __le32 objid
,
260 __le32 par_dirid
, __le32 par_objid
)
262 struct reiserfs_de_head
*deh
;
264 memset(body
, 0, EMPTY_DIR_SIZE
);
265 deh
= (struct reiserfs_de_head
*)body
;
267 /* direntry header of "." */
268 put_deh_offset(&(deh
[0]), DOT_OFFSET
);
269 /* these two are from make_le_item_head, and are are LE */
270 deh
[0].deh_dir_id
= dirid
;
271 deh
[0].deh_objectid
= objid
;
272 deh
[0].deh_state
= 0; /* Endian safe if 0 */
273 put_deh_location(&(deh
[0]), EMPTY_DIR_SIZE
- ROUND_UP(strlen(".")));
274 mark_de_visible(&(deh
[0]));
276 /* direntry header of ".." */
277 put_deh_offset(&(deh
[1]), DOT_DOT_OFFSET
);
278 /* key of ".." for the root directory */
279 /* these two are from the inode, and are are LE */
280 deh
[1].deh_dir_id
= par_dirid
;
281 deh
[1].deh_objectid
= par_objid
;
282 deh
[1].deh_state
= 0; /* Endian safe if 0 */
283 put_deh_location(&(deh
[1]),
284 deh_location(&(deh
[0])) - ROUND_UP(strlen("..")));
285 mark_de_visible(&(deh
[1]));
287 /* copy ".." and "." */
288 memcpy(body
+ deh_location(&(deh
[0])), ".", 1);
289 memcpy(body
+ deh_location(&(deh
[1])), "..", 2);