diff options
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/dir.c | 27 | ||||
-rw-r--r-- | fs/ext2/namei.c | 24 |
2 files changed, 36 insertions, 15 deletions
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 4237722bfd27..6e1d4ab09d72 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -287,17 +287,17 @@ static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode) | |||
287 | } | 287 | } |
288 | 288 | ||
289 | static int | 289 | static int |
290 | ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) | 290 | ext2_readdir(struct file *file, struct dir_context *ctx) |
291 | { | 291 | { |
292 | loff_t pos = filp->f_pos; | 292 | loff_t pos = ctx->pos; |
293 | struct inode *inode = file_inode(filp); | 293 | struct inode *inode = file_inode(file); |
294 | struct super_block *sb = inode->i_sb; | 294 | struct super_block *sb = inode->i_sb; |
295 | unsigned int offset = pos & ~PAGE_CACHE_MASK; | 295 | unsigned int offset = pos & ~PAGE_CACHE_MASK; |
296 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | 296 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
297 | unsigned long npages = dir_pages(inode); | 297 | unsigned long npages = dir_pages(inode); |
298 | unsigned chunk_mask = ~(ext2_chunk_size(inode)-1); | 298 | unsigned chunk_mask = ~(ext2_chunk_size(inode)-1); |
299 | unsigned char *types = NULL; | 299 | unsigned char *types = NULL; |
300 | int need_revalidate = filp->f_version != inode->i_version; | 300 | int need_revalidate = file->f_version != inode->i_version; |
301 | 301 | ||
302 | if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) | 302 | if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) |
303 | return 0; | 303 | return 0; |
@@ -314,16 +314,16 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) | |||
314 | ext2_error(sb, __func__, | 314 | ext2_error(sb, __func__, |
315 | "bad page in #%lu", | 315 | "bad page in #%lu", |
316 | inode->i_ino); | 316 | inode->i_ino); |
317 | filp->f_pos += PAGE_CACHE_SIZE - offset; | 317 | ctx->pos += PAGE_CACHE_SIZE - offset; |
318 | return PTR_ERR(page); | 318 | return PTR_ERR(page); |
319 | } | 319 | } |
320 | kaddr = page_address(page); | 320 | kaddr = page_address(page); |
321 | if (unlikely(need_revalidate)) { | 321 | if (unlikely(need_revalidate)) { |
322 | if (offset) { | 322 | if (offset) { |
323 | offset = ext2_validate_entry(kaddr, offset, chunk_mask); | 323 | offset = ext2_validate_entry(kaddr, offset, chunk_mask); |
324 | filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset; | 324 | ctx->pos = (n<<PAGE_CACHE_SHIFT) + offset; |
325 | } | 325 | } |
326 | filp->f_version = inode->i_version; | 326 | file->f_version = inode->i_version; |
327 | need_revalidate = 0; | 327 | need_revalidate = 0; |
328 | } | 328 | } |
329 | de = (ext2_dirent *)(kaddr+offset); | 329 | de = (ext2_dirent *)(kaddr+offset); |
@@ -336,22 +336,19 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) | |||
336 | return -EIO; | 336 | return -EIO; |
337 | } | 337 | } |
338 | if (de->inode) { | 338 | if (de->inode) { |
339 | int over; | ||
340 | unsigned char d_type = DT_UNKNOWN; | 339 | unsigned char d_type = DT_UNKNOWN; |
341 | 340 | ||
342 | if (types && de->file_type < EXT2_FT_MAX) | 341 | if (types && de->file_type < EXT2_FT_MAX) |
343 | d_type = types[de->file_type]; | 342 | d_type = types[de->file_type]; |
344 | 343 | ||
345 | offset = (char *)de - kaddr; | 344 | if (!dir_emit(ctx, de->name, de->name_len, |
346 | over = filldir(dirent, de->name, de->name_len, | 345 | le32_to_cpu(de->inode), |
347 | (n<<PAGE_CACHE_SHIFT) | offset, | 346 | d_type)) { |
348 | le32_to_cpu(de->inode), d_type); | ||
349 | if (over) { | ||
350 | ext2_put_page(page); | 347 | ext2_put_page(page); |
351 | return 0; | 348 | return 0; |
352 | } | 349 | } |
353 | } | 350 | } |
354 | filp->f_pos += ext2_rec_len_from_disk(de->rec_len); | 351 | ctx->pos += ext2_rec_len_from_disk(de->rec_len); |
355 | } | 352 | } |
356 | ext2_put_page(page); | 353 | ext2_put_page(page); |
357 | } | 354 | } |
@@ -724,7 +721,7 @@ not_empty: | |||
724 | const struct file_operations ext2_dir_operations = { | 721 | const struct file_operations ext2_dir_operations = { |
725 | .llseek = generic_file_llseek, | 722 | .llseek = generic_file_llseek, |
726 | .read = generic_read_dir, | 723 | .read = generic_read_dir, |
727 | .readdir = ext2_readdir, | 724 | .iterate = ext2_readdir, |
728 | .unlocked_ioctl = ext2_ioctl, | 725 | .unlocked_ioctl = ext2_ioctl, |
729 | #ifdef CONFIG_COMPAT | 726 | #ifdef CONFIG_COMPAT |
730 | .compat_ioctl = ext2_compat_ioctl, | 727 | .compat_ioctl = ext2_compat_ioctl, |
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 73b0d9519836..256dd5f4c1c4 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c | |||
@@ -119,6 +119,29 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode | |||
119 | return ext2_add_nondir(dentry, inode); | 119 | return ext2_add_nondir(dentry, inode); |
120 | } | 120 | } |
121 | 121 | ||
122 | static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) | ||
123 | { | ||
124 | struct inode *inode = ext2_new_inode(dir, mode, NULL); | ||
125 | if (IS_ERR(inode)) | ||
126 | return PTR_ERR(inode); | ||
127 | |||
128 | inode->i_op = &ext2_file_inode_operations; | ||
129 | if (ext2_use_xip(inode->i_sb)) { | ||
130 | inode->i_mapping->a_ops = &ext2_aops_xip; | ||
131 | inode->i_fop = &ext2_xip_file_operations; | ||
132 | } else if (test_opt(inode->i_sb, NOBH)) { | ||
133 | inode->i_mapping->a_ops = &ext2_nobh_aops; | ||
134 | inode->i_fop = &ext2_file_operations; | ||
135 | } else { | ||
136 | inode->i_mapping->a_ops = &ext2_aops; | ||
137 | inode->i_fop = &ext2_file_operations; | ||
138 | } | ||
139 | mark_inode_dirty(inode); | ||
140 | d_tmpfile(dentry, inode); | ||
141 | unlock_new_inode(inode); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
122 | static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev) | 145 | static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev) |
123 | { | 146 | { |
124 | struct inode * inode; | 147 | struct inode * inode; |
@@ -398,6 +421,7 @@ const struct inode_operations ext2_dir_inode_operations = { | |||
398 | #endif | 421 | #endif |
399 | .setattr = ext2_setattr, | 422 | .setattr = ext2_setattr, |
400 | .get_acl = ext2_get_acl, | 423 | .get_acl = ext2_get_acl, |
424 | .tmpfile = ext2_tmpfile, | ||
401 | }; | 425 | }; |
402 | 426 | ||
403 | const struct inode_operations ext2_special_inode_operations = { | 427 | const struct inode_operations ext2_special_inode_operations = { |