/[pkg-src]/trunk/kernel26-magellan/patches-2.6.29-r7/0305-2.6.29-ext4-add-EXT4_IOC_ALLOC_DA_BLKS-ioctl.patch |
Contents 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 -
(show 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 | 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 | } |