[Ocfs2-devel] [PATCH] Ocfs2: do not allow fallocate on dir file
Jiaju Zhang
jjzhang.linux at gmail.com
Thu Mar 10 10:33:41 PST 2011
On Fri, Mar 11, 2011 at 12:54 AM, Mark Fasheh <mfasheh at suse.com> wrote:
> On Thu, Mar 10, 2011 at 02:00:33PM +0800, Jiaju Zhang wrote:
>> On Thu, Mar 10, 2011 at 12:25 PM, Mark Fasheh <mfasheh at suse.com> wrote:
>> > On Thu, Mar 10, 2011 at 10:46:33AM +0800, Tao Ma wrote:
>> >> On 03/10/2011 10:27 AM, Sunil Mushran wrote:
>> >> > On 03/09/2011 03:01 PM, Mark Fasheh wrote:
>> >> >> On Fri, Mar 04, 2011 at 03:10:33PM +0800, Li Dongyang wrote:
>> >> >>> @@ -1870,6 +1870,11 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
>> >> >>> goto out_inode_unlock;
>> >> >>> }
>> >> >>>
>> >> >>> + if (!S_ISREG(inode->i_mode)) {
>> >> >>> + ret = -EINVAL;
>> >> >>> + goto out_inode_unlock;
>> >> >>> + }
>> >> >> You might want to move the check into ocfs2_fallocate to mirror what
>> >> >> ocfs2_change_file_space() does. Otherwise, looks like a good catch.
>> >> >>
>> >> >
>> >> > Tristan pointed out that this check was already in ocfs2_change_file_space().
>> >> > So this patch should not be required. Am I missing something?
>> >> This patch is needed since the check is in ocfs2_change_file_space. But
>> >> ocfs2_fallocate calls __ocfs2_change_file_space directly.
>> >
>> > Right.
>>
>> It seems it is not right:-) If I read the code correctly, although
>> ocfs2_fallocate calls __ocfs2_change_file_space directly, however,
>> ocfs2_fallocate is a file operation but not an inode operation,
>> ocfs2_fallocate can only be registered when that file is a regular
>> file, so this patch is not needed.
>
> Please review the code in fs/open.c:do_fallocate()
>
> /*
> * Let individual file system decide if it supports preallocation
> * for directories or not.
> */
> if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
> return -ENODEV;
Yes.
>
> So, sys_fallocate is leaving the decision up to the file system. Therefore I
> think your patch is needed after all :)
Maybe I haven't said more clear about this :-) I mean the check has
been performed before, please see the code in fs/ocfs2/inode.c
<<ocfs2_populate_inode>>:
322 switch (inode->i_mode & S_IFMT) {
323 case S_IFREG:
324 if (use_plocks)
325 inode->i_fop = &ocfs2_fops;
326 else
327 inode->i_fop = &ocfs2_fops_no_plocks;
328 inode->i_op = &ocfs2_file_iops;
329 i_size_write(inode, le64_to_cpu(fe->i_size));
330 break;
331 case S_IFDIR:
332 inode->i_op = &ocfs2_dir_iops;
333 if (use_plocks)
334 inode->i_fop = &ocfs2_dops;
335 else
336 inode->i_fop = &ocfs2_dops_no_plocks;
337 i_size_write(inode, le64_to_cpu(fe->i_size));
338 OCFS2_I(inode)->ip_dir_lock_gen = 1;
339 break;
In line 323, we have checked the inode->i_mode, if it is S_IFREG,
ocfs2_fops will be assigned to inode->i_fop; if it is S_IFDIR,
ocfs2_dops should be assigned. And from the code in fs/ocfs2/file.c:
2626 const struct file_operations ocfs2_fops = {
2627 .llseek = generic_file_llseek,
2628 .read = do_sync_read,
2629 .write = do_sync_write,
2630 .mmap = ocfs2_mmap,
2631 .fsync = ocfs2_sync_file,
2632 .release = ocfs2_file_release,
2633 .open = ocfs2_file_open,
2634 .aio_read = ocfs2_file_aio_read,
2635 .aio_write = ocfs2_file_aio_write,
2636 .unlocked_ioctl = ocfs2_ioctl,
2637 #ifdef CONFIG_COMPAT
2638 .compat_ioctl = ocfs2_compat_ioctl,
2639 #endif
2640 .lock = ocfs2_lock,
2641 .flock = ocfs2_flock,
2642 .splice_read = ocfs2_file_splice_read,
2643 .splice_write = ocfs2_file_splice_write,
2644 .fallocate = ocfs2_fallocate,
2645 };
2646
2647 const struct file_operations ocfs2_dops = {
2648 .llseek = generic_file_llseek,
2649 .read = generic_read_dir,
2650 .readdir = ocfs2_readdir,
2651 .fsync = ocfs2_sync_file,
2652 .release = ocfs2_dir_release,
2653 .open = ocfs2_dir_open,
2654 .unlocked_ioctl = ocfs2_ioctl,
2655 #ifdef CONFIG_COMPAT
2656 .compat_ioctl = ocfs2_compat_ioctl,
2657 #endif
2658 .lock = ocfs2_lock,
2659 .flock = ocfs2_flock,
2660 };
ocfs2_fops has the fallocate field, but ocfs2_dops doesn't have it. So
if the file is a directory, file->f_op->fallocate should be NULL, so
in the function do_fallocate, it should have returned -EOPNOTSUPP
already. So I think that check is not needed. Or am I missing
something?:)
Thanks,
Jiaju
More information about the Ocfs2-devel
mailing list