diff options
Diffstat (limited to 'fs/reiserfs')
-rw-r--r-- | fs/reiserfs/dir.c | 36 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 12 | ||||
-rw-r--r-- | fs/reiserfs/reiserfs.h | 2 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 33 |
4 files changed, 41 insertions, 42 deletions
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 6c2d136561cb..03e4ca5624d6 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -13,14 +13,14 @@ | |||
13 | 13 | ||
14 | extern const struct reiserfs_key MIN_KEY; | 14 | extern const struct reiserfs_key MIN_KEY; |
15 | 15 | ||
16 | static int reiserfs_readdir(struct file *, void *, filldir_t); | 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, | 17 | static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end, |
18 | int datasync); | 18 | int datasync); |
19 | 19 | ||
20 | const struct file_operations reiserfs_dir_operations = { | 20 | const struct file_operations reiserfs_dir_operations = { |
21 | .llseek = generic_file_llseek, | 21 | .llseek = generic_file_llseek, |
22 | .read = generic_read_dir, | 22 | .read = generic_read_dir, |
23 | .readdir = reiserfs_readdir, | 23 | .iterate = reiserfs_readdir, |
24 | .fsync = reiserfs_dir_fsync, | 24 | .fsync = reiserfs_dir_fsync, |
25 | .unlocked_ioctl = reiserfs_ioctl, | 25 | .unlocked_ioctl = reiserfs_ioctl, |
26 | #ifdef CONFIG_COMPAT | 26 | #ifdef CONFIG_COMPAT |
@@ -50,18 +50,15 @@ static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end, | |||
50 | 50 | ||
51 | #define store_ih(where,what) copy_item_head (where, what) | 51 | #define store_ih(where,what) copy_item_head (where, what) |
52 | 52 | ||
53 | static inline bool is_privroot_deh(struct dentry *dir, | 53 | static inline bool is_privroot_deh(struct inode *dir, struct reiserfs_de_head *deh) |
54 | struct reiserfs_de_head *deh) | ||
55 | { | 54 | { |
56 | struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root; | 55 | struct dentry *privroot = REISERFS_SB(dir->i_sb)->priv_root; |
57 | return (dir == dir->d_parent && privroot->d_inode && | 56 | return (privroot->d_inode && |
58 | deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); | 57 | deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); |
59 | } | 58 | } |
60 | 59 | ||
61 | int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | 60 | int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx) |
62 | filldir_t filldir, loff_t *pos) | ||
63 | { | 61 | { |
64 | struct inode *inode = dentry->d_inode; | ||
65 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ | 62 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ |
66 | INITIALIZE_PATH(path_to_entry); | 63 | INITIALIZE_PATH(path_to_entry); |
67 | struct buffer_head *bh; | 64 | struct buffer_head *bh; |
@@ -81,7 +78,7 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
81 | 78 | ||
82 | /* form key for search the next directory entry using f_pos field of | 79 | /* form key for search the next directory entry using f_pos field of |
83 | file structure */ | 80 | file structure */ |
84 | make_cpu_key(&pos_key, inode, *pos ?: DOT_OFFSET, TYPE_DIRENTRY, 3); | 81 | make_cpu_key(&pos_key, inode, ctx->pos ?: DOT_OFFSET, TYPE_DIRENTRY, 3); |
85 | next_pos = cpu_key_k_offset(&pos_key); | 82 | next_pos = cpu_key_k_offset(&pos_key); |
86 | 83 | ||
87 | path_to_entry.reada = PATH_READA; | 84 | path_to_entry.reada = PATH_READA; |
@@ -126,7 +123,6 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
126 | entry_num++, deh++) { | 123 | entry_num++, deh++) { |
127 | int d_reclen; | 124 | int d_reclen; |
128 | char *d_name; | 125 | char *d_name; |
129 | off_t d_off; | ||
130 | ino_t d_ino; | 126 | ino_t d_ino; |
131 | 127 | ||
132 | if (!de_visible(deh)) | 128 | if (!de_visible(deh)) |
@@ -155,11 +151,10 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
155 | } | 151 | } |
156 | 152 | ||
157 | /* Ignore the .reiserfs_priv entry */ | 153 | /* Ignore the .reiserfs_priv entry */ |
158 | if (is_privroot_deh(dentry, deh)) | 154 | if (is_privroot_deh(inode, deh)) |
159 | continue; | 155 | continue; |
160 | 156 | ||
161 | d_off = deh_offset(deh); | 157 | ctx->pos = deh_offset(deh); |
162 | *pos = d_off; | ||
163 | d_ino = deh_objectid(deh); | 158 | d_ino = deh_objectid(deh); |
164 | if (d_reclen <= 32) { | 159 | if (d_reclen <= 32) { |
165 | local_buf = small_buf; | 160 | local_buf = small_buf; |
@@ -187,9 +182,9 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
187 | * the write lock here for other waiters | 182 | * the write lock here for other waiters |
188 | */ | 183 | */ |
189 | reiserfs_write_unlock(inode->i_sb); | 184 | reiserfs_write_unlock(inode->i_sb); |
190 | if (filldir | 185 | if (!dir_emit |
191 | (dirent, local_buf, d_reclen, d_off, d_ino, | 186 | (ctx, local_buf, d_reclen, d_ino, |
192 | DT_UNKNOWN) < 0) { | 187 | DT_UNKNOWN)) { |
193 | reiserfs_write_lock(inode->i_sb); | 188 | reiserfs_write_lock(inode->i_sb); |
194 | if (local_buf != small_buf) { | 189 | if (local_buf != small_buf) { |
195 | kfree(local_buf); | 190 | kfree(local_buf); |
@@ -237,7 +232,7 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
237 | } /* while */ | 232 | } /* while */ |
238 | 233 | ||
239 | end: | 234 | end: |
240 | *pos = next_pos; | 235 | ctx->pos = next_pos; |
241 | pathrelse(&path_to_entry); | 236 | pathrelse(&path_to_entry); |
242 | reiserfs_check_path(&path_to_entry); | 237 | reiserfs_check_path(&path_to_entry); |
243 | out: | 238 | out: |
@@ -245,10 +240,9 @@ out: | |||
245 | return ret; | 240 | return ret; |
246 | } | 241 | } |
247 | 242 | ||
248 | static int reiserfs_readdir(struct file *file, void *dirent, filldir_t filldir) | 243 | static int reiserfs_readdir(struct file *file, struct dir_context *ctx) |
249 | { | 244 | { |
250 | struct dentry *dentry = file->f_path.dentry; | 245 | return reiserfs_readdir_inode(file_inode(file), ctx); |
251 | return reiserfs_readdir_dentry(dentry, dirent, filldir, &file->f_pos); | ||
252 | } | 246 | } |
253 | 247 | ||
254 | /* compose directory item containing "." and ".." entries (entries are | 248 | /* compose directory item containing "." and ".." entries (entries are |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index f844533792ee..0048cc16a6a8 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -2975,16 +2975,19 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh) | |||
2975 | } | 2975 | } |
2976 | 2976 | ||
2977 | /* clm -- taken from fs/buffer.c:block_invalidate_page */ | 2977 | /* clm -- taken from fs/buffer.c:block_invalidate_page */ |
2978 | static void reiserfs_invalidatepage(struct page *page, unsigned long offset) | 2978 | static void reiserfs_invalidatepage(struct page *page, unsigned int offset, |
2979 | unsigned int length) | ||
2979 | { | 2980 | { |
2980 | struct buffer_head *head, *bh, *next; | 2981 | struct buffer_head *head, *bh, *next; |
2981 | struct inode *inode = page->mapping->host; | 2982 | struct inode *inode = page->mapping->host; |
2982 | unsigned int curr_off = 0; | 2983 | unsigned int curr_off = 0; |
2984 | unsigned int stop = offset + length; | ||
2985 | int partial_page = (offset || length < PAGE_CACHE_SIZE); | ||
2983 | int ret = 1; | 2986 | int ret = 1; |
2984 | 2987 | ||
2985 | BUG_ON(!PageLocked(page)); | 2988 | BUG_ON(!PageLocked(page)); |
2986 | 2989 | ||
2987 | if (offset == 0) | 2990 | if (!partial_page) |
2988 | ClearPageChecked(page); | 2991 | ClearPageChecked(page); |
2989 | 2992 | ||
2990 | if (!page_has_buffers(page)) | 2993 | if (!page_has_buffers(page)) |
@@ -2996,6 +2999,9 @@ static void reiserfs_invalidatepage(struct page *page, unsigned long offset) | |||
2996 | unsigned int next_off = curr_off + bh->b_size; | 2999 | unsigned int next_off = curr_off + bh->b_size; |
2997 | next = bh->b_this_page; | 3000 | next = bh->b_this_page; |
2998 | 3001 | ||
3002 | if (next_off > stop) | ||
3003 | goto out; | ||
3004 | |||
2999 | /* | 3005 | /* |
3000 | * is this block fully invalidated? | 3006 | * is this block fully invalidated? |
3001 | */ | 3007 | */ |
@@ -3014,7 +3020,7 @@ static void reiserfs_invalidatepage(struct page *page, unsigned long offset) | |||
3014 | * The get_block cached value has been unconditionally invalidated, | 3020 | * The get_block cached value has been unconditionally invalidated, |
3015 | * so real IO is not possible anymore. | 3021 | * so real IO is not possible anymore. |
3016 | */ | 3022 | */ |
3017 | if (!offset && ret) { | 3023 | if (!partial_page && ret) { |
3018 | ret = try_to_release_page(page, 0); | 3024 | ret = try_to_release_page(page, 0); |
3019 | /* maybe should BUG_ON(!ret); - neilb */ | 3025 | /* maybe should BUG_ON(!ret); - neilb */ |
3020 | } | 3026 | } |
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index 157e474ab303..3df5ce6c724d 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h | |||
@@ -2709,7 +2709,7 @@ extern const struct inode_operations reiserfs_dir_inode_operations; | |||
2709 | extern const struct inode_operations reiserfs_symlink_inode_operations; | 2709 | extern const struct inode_operations reiserfs_symlink_inode_operations; |
2710 | extern const struct inode_operations reiserfs_special_inode_operations; | 2710 | extern const struct inode_operations reiserfs_special_inode_operations; |
2711 | extern const struct file_operations reiserfs_dir_operations; | 2711 | extern const struct file_operations reiserfs_dir_operations; |
2712 | int reiserfs_readdir_dentry(struct dentry *, void *, filldir_t, loff_t *); | 2712 | int reiserfs_readdir_inode(struct inode *, struct dir_context *); |
2713 | 2713 | ||
2714 | /* tail_conversion.c */ | 2714 | /* tail_conversion.c */ |
2715 | int direct2indirect(struct reiserfs_transaction_handle *, struct inode *, | 2715 | int direct2indirect(struct reiserfs_transaction_handle *, struct inode *, |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 821bcf70e467..c69cdd749f09 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -171,6 +171,7 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags) | |||
171 | * modifying extended attributes. This includes operations such as permissions | 171 | * modifying extended attributes. This includes operations such as permissions |
172 | * or ownership changes, object deletions, etc. */ | 172 | * or ownership changes, object deletions, etc. */ |
173 | struct reiserfs_dentry_buf { | 173 | struct reiserfs_dentry_buf { |
174 | struct dir_context ctx; | ||
174 | struct dentry *xadir; | 175 | struct dentry *xadir; |
175 | int count; | 176 | int count; |
176 | struct dentry *dentries[8]; | 177 | struct dentry *dentries[8]; |
@@ -223,9 +224,8 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
223 | { | 224 | { |
224 | struct dentry *dir; | 225 | struct dentry *dir; |
225 | int i, err = 0; | 226 | int i, err = 0; |
226 | loff_t pos = 0; | ||
227 | struct reiserfs_dentry_buf buf = { | 227 | struct reiserfs_dentry_buf buf = { |
228 | .count = 0, | 228 | .ctx.actor = fill_with_dentries, |
229 | }; | 229 | }; |
230 | 230 | ||
231 | /* Skip out, an xattr has no xattrs associated with it */ | 231 | /* Skip out, an xattr has no xattrs associated with it */ |
@@ -249,29 +249,27 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
249 | reiserfs_write_lock(inode->i_sb); | 249 | reiserfs_write_lock(inode->i_sb); |
250 | 250 | ||
251 | buf.xadir = dir; | 251 | buf.xadir = dir; |
252 | err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); | 252 | while (1) { |
253 | while ((err == 0 || err == -ENOSPC) && buf.count) { | 253 | err = reiserfs_readdir_inode(dir->d_inode, &buf.ctx); |
254 | err = 0; | 254 | if (err) |
255 | 255 | break; | |
256 | for (i = 0; i < buf.count && buf.dentries[i]; i++) { | 256 | if (!buf.count) |
257 | int lerr = 0; | 257 | break; |
258 | for (i = 0; !err && i < buf.count && buf.dentries[i]; i++) { | ||
258 | struct dentry *dentry = buf.dentries[i]; | 259 | struct dentry *dentry = buf.dentries[i]; |
259 | 260 | ||
260 | if (err == 0 && !S_ISDIR(dentry->d_inode->i_mode)) | 261 | if (!S_ISDIR(dentry->d_inode->i_mode)) |
261 | lerr = action(dentry, data); | 262 | err = action(dentry, data); |
262 | 263 | ||
263 | dput(dentry); | 264 | dput(dentry); |
264 | buf.dentries[i] = NULL; | 265 | buf.dentries[i] = NULL; |
265 | err = lerr ?: err; | ||
266 | } | 266 | } |
267 | if (err) | ||
268 | break; | ||
267 | buf.count = 0; | 269 | buf.count = 0; |
268 | if (!err) | ||
269 | err = reiserfs_readdir_dentry(dir, &buf, | ||
270 | fill_with_dentries, &pos); | ||
271 | } | 270 | } |
272 | mutex_unlock(&dir->d_inode->i_mutex); | 271 | mutex_unlock(&dir->d_inode->i_mutex); |
273 | 272 | ||
274 | /* Clean up after a failed readdir */ | ||
275 | cleanup_dentry_buf(&buf); | 273 | cleanup_dentry_buf(&buf); |
276 | 274 | ||
277 | if (!err) { | 275 | if (!err) { |
@@ -800,6 +798,7 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name) | |||
800 | } | 798 | } |
801 | 799 | ||
802 | struct listxattr_buf { | 800 | struct listxattr_buf { |
801 | struct dir_context ctx; | ||
803 | size_t size; | 802 | size_t size; |
804 | size_t pos; | 803 | size_t pos; |
805 | char *buf; | 804 | char *buf; |
@@ -845,8 +844,8 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |||
845 | { | 844 | { |
846 | struct dentry *dir; | 845 | struct dentry *dir; |
847 | int err = 0; | 846 | int err = 0; |
848 | loff_t pos = 0; | ||
849 | struct listxattr_buf buf = { | 847 | struct listxattr_buf buf = { |
848 | .ctx.actor = listxattr_filler, | ||
850 | .dentry = dentry, | 849 | .dentry = dentry, |
851 | .buf = buffer, | 850 | .buf = buffer, |
852 | .size = buffer ? size : 0, | 851 | .size = buffer ? size : 0, |
@@ -868,7 +867,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |||
868 | } | 867 | } |
869 | 868 | ||
870 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); | 869 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); |
871 | err = reiserfs_readdir_dentry(dir, &buf, listxattr_filler, &pos); | 870 | err = reiserfs_readdir_inode(dir->d_inode, &buf.ctx); |
872 | mutex_unlock(&dir->d_inode->i_mutex); | 871 | mutex_unlock(&dir->d_inode->i_mutex); |
873 | 872 | ||
874 | if (!err) | 873 | if (!err) |