/[pkg-src]/trunk/kernel26-magellan/patches-2.6.29-r7/0305-2.6.29-ext4-add-EXT4_IOC_ALLOC_DA_BLKS-ioctl.patch |
Annotation of /trunk/kernel26-magellan/patches-2.6.29-r7/0305-2.6.29-ext4-add-EXT4_IOC_ALLOC_DA_BLKS-ioctl.patch
Parent Directory | Revision Log
Revision 857 -
(hide annotations)
(download)
Tue Jun 30 20:01:52 2009 UTC (15 years, 3 months ago) by niro
File size: 4130 byte(s)
Tue Jun 30 20:01:52 2009 UTC (15 years, 3 months ago) by niro
File size: 4130 byte(s)
-2.6.29-magellan-r7: updated to linux-2.6.29.5
1 | niro | 857 | Added-By: Gordon Malm <gengor@gentoo.org> |
2 | |||
3 | --- | ||
4 | From: Theodore Ts'o <tytso@mit.edu> | ||
5 | Date: Thu, 26 Feb 2009 06:04:07 +0000 (-0500) | ||
6 | Subject: ext4: add EXT4_IOC_ALLOC_DA_BLKS ioctl | ||
7 | X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftytso%2Fext4.git;a=commitdiff_plain;h=3bf3342f394d72ed2ec7e77b5b39e1b50fad8284 | ||
8 | |||
9 | ext4: add EXT4_IOC_ALLOC_DA_BLKS ioctl | ||
10 | |||
11 | Add an ioctl which forces all of the delay allocated blocks to be | ||
12 | allocated. This also provides a function ext4_alloc_da_blocks() which | ||
13 | will be used by the following commits to force files to be fully | ||
14 | allocated to preserve application-expected ext3 behaviour. | ||
15 | |||
16 | Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> | ||
17 | --- | ||
18 | |||
19 | diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h | ||
20 | index 684a063..ea51c89 100644 | ||
21 | --- a/fs/ext4/ext4.h | ||
22 | +++ b/fs/ext4/ext4.h | ||
23 | @@ -316,7 +316,9 @@ struct ext4_new_group_data { | ||
24 | #define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) | ||
25 | #define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input) | ||
26 | #define EXT4_IOC_MIGRATE _IO('f', 9) | ||
27 | + /* note ioctl 10 reserved for an early version of the FIEMAP ioctl */ | ||
28 | /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */ | ||
29 | +#define EXT4_IOC_ALLOC_DA_BLKS _IO('f', 12) | ||
30 | |||
31 | /* | ||
32 | * ioctl commands in 32 bit emulation | ||
33 | @@ -1093,6 +1095,7 @@ extern int ext4_can_truncate(struct inode *inode); | ||
34 | extern void ext4_truncate(struct inode *); | ||
35 | extern void ext4_set_inode_flags(struct inode *); | ||
36 | extern void ext4_get_inode_flags(struct ext4_inode_info *); | ||
37 | +extern int ext4_alloc_da_blocks(struct inode *inode); | ||
38 | extern void ext4_set_aops(struct inode *inode); | ||
39 | extern int ext4_writepage_trans_blocks(struct inode *); | ||
40 | extern int ext4_meta_trans_blocks(struct inode *, int nrblocks, int idxblocks); | ||
41 | diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c | ||
42 | index c67f46e..ead57ab 100644 | ||
43 | --- a/fs/ext4/inode.c | ||
44 | +++ b/fs/ext4/inode.c | ||
45 | @@ -2807,6 +2807,48 @@ out: | ||
46 | return; | ||
47 | } | ||
48 | |||
49 | +/* | ||
50 | + * Force all delayed allocation blocks to be allocated for a given inode. | ||
51 | + */ | ||
52 | +int ext4_alloc_da_blocks(struct inode *inode) | ||
53 | +{ | ||
54 | + if (!EXT4_I(inode)->i_reserved_data_blocks && | ||
55 | + !EXT4_I(inode)->i_reserved_meta_blocks) | ||
56 | + return 0; | ||
57 | + | ||
58 | + /* | ||
59 | + * We do something simple for now. The filemap_flush() will | ||
60 | + * also start triggering a write of the data blocks, which is | ||
61 | + * not strictly speaking necessary (and for users of | ||
62 | + * laptop_mode, not even desirable). However, to do otherwise | ||
63 | + * would require replicating code paths in: | ||
64 | + * | ||
65 | + * ext4_da_writepages() -> | ||
66 | + * write_cache_pages() ---> (via passed in callback function) | ||
67 | + * __mpage_da_writepage() --> | ||
68 | + * mpage_add_bh_to_extent() | ||
69 | + * mpage_da_map_blocks() | ||
70 | + * | ||
71 | + * The problem is that write_cache_pages(), located in | ||
72 | + * mm/page-writeback.c, marks pages clean in preparation for | ||
73 | + * doing I/O, which is not desirable if we're not planning on | ||
74 | + * doing I/O at all. | ||
75 | + * | ||
76 | + * We could call write_cache_pages(), and then redirty all of | ||
77 | + * the pages by calling redirty_page_for_writeback() but that | ||
78 | + * would be ugly in the extreme. So instead we would need to | ||
79 | + * replicate parts of the code in the above functions, | ||
80 | + * simplifying them becuase we wouldn't actually intend to | ||
81 | + * write out the pages, but rather only collect contiguous | ||
82 | + * logical block extents, call the multi-block allocator, and | ||
83 | + * then update the buffer heads with the block allocations. | ||
84 | + * | ||
85 | + * For now, though, we'll cheat by calling filemap_flush(), | ||
86 | + * which will map the blocks, and start the I/O, but not | ||
87 | + * actually wait for the I/O to complete. | ||
88 | + */ | ||
89 | + return filemap_flush(inode->i_mapping); | ||
90 | +} | ||
91 | |||
92 | /* | ||
93 | * bmap() is special. It gets used by applications such as lilo and by | ||
94 | diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c | ||
95 | index 22dd29f..91e75f7 100644 | ||
96 | --- a/fs/ext4/ioctl.c | ||
97 | +++ b/fs/ext4/ioctl.c | ||
98 | @@ -262,6 +262,20 @@ setversion_out: | ||
99 | return err; | ||
100 | } | ||
101 | |||
102 | + case EXT4_IOC_ALLOC_DA_BLKS: | ||
103 | + { | ||
104 | + int err; | ||
105 | + if (!is_owner_or_cap(inode)) | ||
106 | + return -EACCES; | ||
107 | + | ||
108 | + err = mnt_want_write(filp->f_path.mnt); | ||
109 | + if (err) | ||
110 | + return err; | ||
111 | + err = ext4_alloc_da_blocks(inode); | ||
112 | + mnt_drop_write(filp->f_path.mnt); | ||
113 | + return err; | ||
114 | + } | ||
115 | + | ||
116 | default: | ||
117 | return -ENOTTY; | ||
118 | } |