diff options
author | Jeff Mahoney <jeffm@suse.com> | 2009-03-30 14:02:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-30 15:16:38 -0400 |
commit | a41f1a4715f26f7bc4d047d0bc7710145c8e69c7 (patch) | |
tree | 8b5d94368e774ec490619593300e8b3f4b7c5cb1 /fs/reiserfs/dir.c | |
parent | 0ab2621ebd9a28bf7a524ecd50d492a10579dfcc (diff) |
reiserfs: use generic readdir for operations across all xattrs
The current reiserfs xattr implementation open codes reiserfs_readdir
and frees the path before calling the filldir function. Typically, the
filldir function is something that modifies the file system, such as a
chown or an inode deletion that also require reading of an inode
associated with each direntry. Since the file system is modified, the
path retained becomes invalid for the next run. In addition, it runs
backwards in attempt to minimize activity.
This is clearly suboptimal from a code cleanliness perspective as well
as performance-wise.
This patch implements a generic reiserfs_for_each_xattr that uses the
generic readdir and a specific filldir routine that simply populates an
array of dentries and then performs a specific operation on them. When
all files have been operated on, it then calls the operation on the
directory itself.
The result is a noticable code reduction and better performance.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/reiserfs/dir.c')
-rw-r--r-- | fs/reiserfs/dir.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index e6b03d2020c1..67a80d7e59e2 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -41,10 +41,10 @@ static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, | |||
41 | 41 | ||
42 | #define store_ih(where,what) copy_item_head (where, what) | 42 | #define store_ih(where,what) copy_item_head (where, what) |
43 | 43 | ||
44 | // | 44 | int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, |
45 | static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 45 | filldir_t filldir, loff_t *pos) |
46 | { | 46 | { |
47 | struct inode *inode = filp->f_path.dentry->d_inode; | 47 | struct inode *inode = dentry->d_inode; |
48 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ | 48 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ |
49 | INITIALIZE_PATH(path_to_entry); | 49 | INITIALIZE_PATH(path_to_entry); |
50 | struct buffer_head *bh; | 50 | struct buffer_head *bh; |
@@ -64,13 +64,9 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
64 | 64 | ||
65 | /* form key for search the next directory entry using f_pos field of | 65 | /* form key for search the next directory entry using f_pos field of |
66 | file structure */ | 66 | file structure */ |
67 | make_cpu_key(&pos_key, inode, | 67 | make_cpu_key(&pos_key, inode, *pos ?: DOT_OFFSET, TYPE_DIRENTRY, 3); |
68 | (filp->f_pos) ? (filp->f_pos) : DOT_OFFSET, TYPE_DIRENTRY, | ||
69 | 3); | ||
70 | next_pos = cpu_key_k_offset(&pos_key); | 68 | next_pos = cpu_key_k_offset(&pos_key); |
71 | 69 | ||
72 | /* reiserfs_warning (inode->i_sb, "reiserfs_readdir 1: f_pos = %Ld", filp->f_pos); */ | ||
73 | |||
74 | path_to_entry.reada = PATH_READA; | 70 | path_to_entry.reada = PATH_READA; |
75 | while (1) { | 71 | while (1) { |
76 | research: | 72 | research: |
@@ -144,7 +140,7 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
144 | /* Ignore the .reiserfs_priv entry */ | 140 | /* Ignore the .reiserfs_priv entry */ |
145 | if (reiserfs_xattrs(inode->i_sb) && | 141 | if (reiserfs_xattrs(inode->i_sb) && |
146 | !old_format_only(inode->i_sb) && | 142 | !old_format_only(inode->i_sb) && |
147 | filp->f_path.dentry == inode->i_sb->s_root && | 143 | dentry == inode->i_sb->s_root && |
148 | REISERFS_SB(inode->i_sb)->priv_root && | 144 | REISERFS_SB(inode->i_sb)->priv_root && |
149 | REISERFS_SB(inode->i_sb)->priv_root->d_inode | 145 | REISERFS_SB(inode->i_sb)->priv_root->d_inode |
150 | && deh_objectid(deh) == | 146 | && deh_objectid(deh) == |
@@ -156,7 +152,7 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
156 | } | 152 | } |
157 | 153 | ||
158 | d_off = deh_offset(deh); | 154 | d_off = deh_offset(deh); |
159 | filp->f_pos = d_off; | 155 | *pos = d_off; |
160 | d_ino = deh_objectid(deh); | 156 | d_ino = deh_objectid(deh); |
161 | if (d_reclen <= 32) { | 157 | if (d_reclen <= 32) { |
162 | local_buf = small_buf; | 158 | local_buf = small_buf; |
@@ -223,15 +219,21 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
223 | 219 | ||
224 | } /* while */ | 220 | } /* while */ |
225 | 221 | ||
226 | end: | 222 | end: |
227 | filp->f_pos = next_pos; | 223 | *pos = next_pos; |
228 | pathrelse(&path_to_entry); | 224 | pathrelse(&path_to_entry); |
229 | reiserfs_check_path(&path_to_entry); | 225 | reiserfs_check_path(&path_to_entry); |
230 | out: | 226 | out: |
231 | reiserfs_write_unlock(inode->i_sb); | 227 | reiserfs_write_unlock(inode->i_sb); |
232 | return ret; | 228 | return ret; |
233 | } | 229 | } |
234 | 230 | ||
231 | static int reiserfs_readdir(struct file *file, void *dirent, filldir_t filldir) | ||
232 | { | ||
233 | struct dentry *dentry = file->f_path.dentry; | ||
234 | return reiserfs_readdir_dentry(dentry, dirent, filldir, &file->f_pos); | ||
235 | } | ||
236 | |||
235 | /* compose directory item containing "." and ".." entries (entries are | 237 | /* compose directory item containing "." and ".." entries (entries are |
236 | not aligned to 4 byte boundary) */ | 238 | not aligned to 4 byte boundary) */ |
237 | /* the last four params are LE */ | 239 | /* the last four params are LE */ |