update to rc6, and verified pass fsx/dbench
[ext4-patch-queue.git] / ext4-nanosecond-patch
blobd1a693ef1840a843ca5df1d82f99bd6abb1d9768
1 This patch is a spinoff of the old nanosecond patches.
3 It includes some cleanups and addition of a creation timestamp. The
4 EXT3_FEATURE_RO_COMPAT_EXTRA_ISIZE flag has also been added along with
5 s_{min, want}_extra_isize fields in struct ext3_super_block.
7 Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
8 Signed-off-by: Kalpak Shah <kalpak@clusterfs.com>
9 Signed-off-by: Eric Sandeen <sandeen@redhat.com>
10 Signed-off-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
11 Signed-off-by: Mingming Cao <cmm@us.ibm.com>
13 Index: linux-2.6.22-rc4/fs/ext4/ialloc.c
14 ===================================================================
15 --- linux-2.6.22-rc4.orig/fs/ext4/ialloc.c      2007-06-11 17:22:15.000000000 -0700
16 +++ linux-2.6.22-rc4/fs/ext4/ialloc.c   2007-06-11 17:39:05.000000000 -0700
17 @@ -563,7 +563,8 @@
18         inode->i_ino = ino;
19         /* This is the optimal IO size (for stat), not the fs block size */
20         inode->i_blocks = 0;
21 -       inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
22 +       inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime =
23 +                                                      ext4_current_time(inode);
25         memset(ei->i_data, 0, sizeof(ei->i_data));
26         ei->i_dir_start_lookup = 0;
27 @@ -595,9 +596,8 @@
28         spin_unlock(&sbi->s_next_gen_lock);
30         ei->i_state = EXT4_STATE_NEW;
31 -       ei->i_extra_isize =
32 -               (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) ?
33 -               sizeof(struct ext4_inode) - EXT4_GOOD_OLD_INODE_SIZE : 0;
35 +       ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize;
37         ret = inode;
38         if(DQUOT_ALLOC_INODE(inode)) {
39 Index: linux-2.6.22-rc4/fs/ext4/inode.c
40 ===================================================================
41 --- linux-2.6.22-rc4.orig/fs/ext4/inode.c       2007-06-11 17:24:28.000000000 -0700
42 +++ linux-2.6.22-rc4/fs/ext4/inode.c    2007-06-11 17:39:05.000000000 -0700
43 @@ -726,7 +726,7 @@
45         /* We are done with atomic stuff, now do the rest of housekeeping */
47 -       inode->i_ctime = CURRENT_TIME_SEC;
48 +       inode->i_ctime = ext4_current_time(inode);
49         ext4_mark_inode_dirty(handle, inode);
51         /* had we spliced it onto indirect block? */
52 @@ -2375,7 +2375,7 @@
53         ext4_discard_reservation(inode);
55         mutex_unlock(&ei->truncate_mutex);
56 -       inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
57 +       inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
58         ext4_mark_inode_dirty(handle, inode);
60         /*
61 @@ -2629,10 +2629,6 @@
62         }
63         inode->i_nlink = le16_to_cpu(raw_inode->i_links_count);
64         inode->i_size = le32_to_cpu(raw_inode->i_size);
65 -       inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
66 -       inode->i_ctime.tv_sec = (signed)le32_to_cpu(raw_inode->i_ctime);
67 -       inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
68 -       inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
70         ei->i_state = 0;
71         ei->i_dir_start_lookup = 0;
72 @@ -2708,6 +2704,11 @@
73         } else
74                 ei->i_extra_isize = 0;
76 +       EXT4_INODE_GET_XTIME(i_ctime, inode, raw_inode);
77 +       EXT4_INODE_GET_XTIME(i_mtime, inode, raw_inode);
78 +       EXT4_INODE_GET_XTIME(i_atime, inode, raw_inode);
79 +       EXT4_EINODE_GET_XTIME(i_crtime, ei, raw_inode);
81         if (S_ISREG(inode->i_mode)) {
82                 inode->i_op = &ext4_file_inode_operations;
83                 inode->i_fop = &ext4_file_operations;
84 @@ -2789,9 +2790,12 @@
85         }
86         raw_inode->i_links_count = cpu_to_le16(inode->i_nlink);
87         raw_inode->i_size = cpu_to_le32(ei->i_disksize);
88 -       raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
89 -       raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
90 -       raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
92 +       EXT4_INODE_SET_XTIME(i_ctime, inode, raw_inode);
93 +       EXT4_INODE_SET_XTIME(i_mtime, inode, raw_inode);
94 +       EXT4_INODE_SET_XTIME(i_atime, inode, raw_inode);
95 +       EXT4_EINODE_SET_XTIME(i_crtime, ei, raw_inode);
97         raw_inode->i_blocks = cpu_to_le32(inode->i_blocks);
98         raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
99         raw_inode->i_flags = cpu_to_le32(ei->i_flags);
100 Index: linux-2.6.22-rc4/fs/ext4/ioctl.c
101 ===================================================================
102 --- linux-2.6.22-rc4.orig/fs/ext4/ioctl.c       2007-06-11 17:25:11.000000000 -0700
103 +++ linux-2.6.22-rc4/fs/ext4/ioctl.c    2007-06-11 17:39:05.000000000 -0700
104 @@ -97,7 +97,7 @@
105                 ei->i_flags = flags;
107                 ext4_set_inode_flags(inode);
108 -               inode->i_ctime = CURRENT_TIME_SEC;
109 +               inode->i_ctime = ext4_current_time(inode);
111                 err = ext4_mark_iloc_dirty(handle, inode, &iloc);
112  flags_err:
113 @@ -134,7 +134,7 @@
114                         return PTR_ERR(handle);
115                 err = ext4_reserve_inode_write(handle, inode, &iloc);
116                 if (err == 0) {
117 -                       inode->i_ctime = CURRENT_TIME_SEC;
118 +                       inode->i_ctime = ext4_current_time(inode);
119                         inode->i_generation = generation;
120                         err = ext4_mark_iloc_dirty(handle, inode, &iloc);
121                 }
122 Index: linux-2.6.22-rc4/fs/ext4/namei.c
123 ===================================================================
124 --- linux-2.6.22-rc4.orig/fs/ext4/namei.c       2007-06-11 17:22:15.000000000 -0700
125 +++ linux-2.6.22-rc4/fs/ext4/namei.c    2007-06-11 17:39:05.000000000 -0700
126 @@ -1285,7 +1285,7 @@
127          * happen is that the times are slightly out of date
128          * and/or different from the directory change time.
129          */
130 -       dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
131 +       dir->i_mtime = dir->i_ctime = ext4_current_time(dir);
132         ext4_update_dx_flag(dir);
133         dir->i_version++;
134         ext4_mark_inode_dirty(handle, dir);
135 @@ -2046,7 +2046,7 @@
136          * recovery. */
137         inode->i_size = 0;
138         ext4_orphan_add(handle, inode);
139 -       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
140 +       inode->i_ctime = dir->i_ctime = dir->i_mtime = ext4_current_time(inode);
141         ext4_mark_inode_dirty(handle, inode);
142         drop_nlink(dir);
143         ext4_update_dx_flag(dir);
144 @@ -2096,13 +2096,13 @@
145         retval = ext4_delete_entry(handle, dir, de, bh);
146         if (retval)
147                 goto end_unlink;
148 -       dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
149 +       dir->i_ctime = dir->i_mtime = ext4_current_time(dir);
150         ext4_update_dx_flag(dir);
151         ext4_mark_inode_dirty(handle, dir);
152         drop_nlink(inode);
153         if (!inode->i_nlink)
154                 ext4_orphan_add(handle, inode);
155 -       inode->i_ctime = dir->i_ctime;
156 +       inode->i_ctime = ext4_current_time(inode);
157         ext4_mark_inode_dirty(handle, inode);
158         retval = 0;
160 @@ -2193,7 +2193,7 @@
161         if (IS_DIRSYNC(dir))
162                 handle->h_sync = 1;
164 -       inode->i_ctime = CURRENT_TIME_SEC;
165 +       inode->i_ctime = ext4_current_time(inode);
166         inc_nlink(inode);
167         atomic_inc(&inode->i_count);
169 @@ -2295,7 +2295,7 @@
170          * Like most other Unix systems, set the ctime for inodes on a
171          * rename.
172          */
173 -       old_inode->i_ctime = CURRENT_TIME_SEC;
174 +       old_inode->i_ctime = ext4_current_time(old_inode);
175         ext4_mark_inode_dirty(handle, old_inode);
177         /*
178 @@ -2328,9 +2328,9 @@
180         if (new_inode) {
181                 drop_nlink(new_inode);
182 -               new_inode->i_ctime = CURRENT_TIME_SEC;
183 +               new_inode->i_ctime = ext4_current_time(new_inode);
184         }
185 -       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
186 +       old_dir->i_ctime = old_dir->i_mtime = ext4_current_time(old_dir);
187         ext4_update_dx_flag(old_dir);
188         if (dir_bh) {
189                 BUFFER_TRACE(dir_bh, "get_write_access");
190 Index: linux-2.6.22-rc4/fs/ext4/super.c
191 ===================================================================
192 --- linux-2.6.22-rc4.orig/fs/ext4/super.c       2007-06-11 17:28:09.000000000 -0700
193 +++ linux-2.6.22-rc4/fs/ext4/super.c    2007-06-11 17:39:05.000000000 -0700
194 @@ -1642,6 +1642,8 @@
195                                 sbi->s_inode_size);
196                         goto failed_mount;
197                 }
198 +               if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE)
199 +                       sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2);
200         }
201         sbi->s_frag_size = EXT4_MIN_FRAG_SIZE <<
202                                    le32_to_cpu(es->s_log_frag_size);
203 @@ -1865,6 +1867,32 @@
204         }
206         ext4_setup_super (sb, es, sb->s_flags & MS_RDONLY);
208 +       /* determine the minimum size of new large inodes, if present */
209 +       if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) {
210 +               sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
211 +                                                    EXT4_GOOD_OLD_INODE_SIZE;
212 +               if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
213 +                                      EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)) {
214 +                       if (sbi->s_want_extra_isize <
215 +                           le16_to_cpu(es->s_want_extra_isize))
216 +                               sbi->s_want_extra_isize =
217 +                                       le16_to_cpu(es->s_want_extra_isize);
218 +                       if (sbi->s_want_extra_isize <
219 +                           le16_to_cpu(es->s_min_extra_isize))
220 +                               sbi->s_want_extra_isize =
221 +                                       le16_to_cpu(es->s_min_extra_isize);
222 +               }
223 +       }
224 +       /* Check if enough inode space is available */
225 +       if (EXT4_GOOD_OLD_INODE_SIZE + sbi->s_want_extra_isize >
226 +                                                       sbi->s_inode_size) {
227 +               sbi->s_want_extra_isize = sizeof(struct ext4_inode) -
228 +                                                      EXT4_GOOD_OLD_INODE_SIZE;
229 +               printk(KERN_INFO "EXT4-fs: required extra inode space not"
230 +                       "available.\n");
231 +       }
233         /*
234          * akpm: core read_super() calls in here with the superblock locked.
235          * That deadlocks, because orphan cleanup needs to lock the superblock
236 Index: linux-2.6.22-rc4/fs/ext4/xattr.c
237 ===================================================================
238 --- linux-2.6.22-rc4.orig/fs/ext4/xattr.c       2007-06-11 17:22:15.000000000 -0700
239 +++ linux-2.6.22-rc4/fs/ext4/xattr.c    2007-06-11 17:39:05.000000000 -0700
240 @@ -1013,7 +1013,7 @@
241         }
242         if (!error) {
243                 ext4_xattr_update_super_block(handle, inode->i_sb);
244 -               inode->i_ctime = CURRENT_TIME_SEC;
245 +               inode->i_ctime = ext4_current_time(inode);
246                 error = ext4_mark_iloc_dirty(handle, inode, &is.iloc);
247                 /*
248                  * The bh is consumed by ext4_mark_iloc_dirty, even with
249 Index: linux-2.6.22-rc4/include/linux/ext4_fs.h
250 ===================================================================
251 --- linux-2.6.22-rc4.orig/include/linux/ext4_fs.h       2007-06-11 17:36:13.000000000 -0700
252 +++ linux-2.6.22-rc4/include/linux/ext4_fs.h    2007-06-11 17:41:55.000000000 -0700
253 @@ -288,7 +288,7 @@
254         __le16  i_uid;          /* Low 16 bits of Owner Uid */
255         __le32  i_size;         /* Size in bytes */
256         __le32  i_atime;        /* Access time */
257 -       __le32  i_ctime;        /* Creation time */
258 +       __le32  i_ctime;        /* Inode Change time */
259         __le32  i_mtime;        /* Modification time */
260         __le32  i_dtime;        /* Deletion Time */
261         __le16  i_gid;          /* Low 16 bits of Group Id */
262 @@ -337,10 +337,74 @@
263         } osd2;                         /* OS dependent 2 */
264         __le16  i_extra_isize;
265         __le16  i_pad1;
266 +       __le32  i_ctime_extra;  /* extra Change time      (nsec << 2 | epoch) */
267 +       __le32  i_mtime_extra;  /* extra Modification time(nsec << 2 | epoch) */
268 +       __le32  i_atime_extra;  /* extra Access time      (nsec << 2 | epoch) */
269 +       __le32  i_crtime;       /* File Creation time */
270 +       __le32  i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
271  };
273  #define i_size_high    i_dir_acl
275 +#define EXT4_EPOCH_BITS 2
276 +#define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1)
277 +#define EXT4_NSEC_MASK  (~0UL << EXT4_EPOCH_BITS)
279 +#define EXT4_FITS_IN_INODE(ext4_inode, einode, field)  \
280 +       ((offsetof(typeof(*ext4_inode), field) +        \
281 +         sizeof((ext4_inode)->field))                  \
282 +       <= (EXT4_GOOD_OLD_INODE_SIZE +                  \
283 +           (einode)->i_extra_isize))                   \
285 +static inline __le32 ext4_encode_extra_time(struct timespec *time)
287 +       return cpu_to_le32((sizeof(time->tv_sec) > 4 ?
288 +                          time->tv_sec >> 32 : 0) |
289 +                          ((time->tv_nsec << 2) & EXT4_NSEC_MASK));
292 +static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra)
294 +       if (sizeof(time->tv_sec) > 4)
295 +              time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK)
296 +                              << 32;
297 +       time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> 2;
300 +#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode)                         \
301 +do {                                                                          \
302 +       (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec);               \
303 +       if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra))     \
304 +               (raw_inode)->xtime ## _extra =                                 \
305 +                               ext4_encode_extra_time(&(inode)->xtime);       \
306 +} while (0)
308 +#define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode)                               \
309 +do {                                                                          \
310 +       if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime))                      \
311 +               (raw_inode)->xtime = cpu_to_le32((einode)->xtime.tv_sec);      \
312 +       if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra))            \
313 +               (raw_inode)->xtime ## _extra =                                 \
314 +                               ext4_encode_extra_time(&(einode)->xtime);      \
315 +} while (0)
317 +#define EXT4_INODE_GET_XTIME(xtime, inode, raw_inode)                         \
318 +do {                                                                          \
319 +       (inode)->xtime.tv_sec = le32_to_cpu((raw_inode)->xtime);               \
320 +       if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra))     \
321 +               ext4_decode_extra_time(&(inode)->xtime,                        \
322 +                                      raw_inode->xtime ## _extra);            \
323 +} while (0)
325 +#define EXT4_EINODE_GET_XTIME(xtime, einode, raw_inode)                               \
326 +do {                                                                          \
327 +       if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime))                      \
328 +               (einode)->xtime.tv_sec = le32_to_cpu((raw_inode)->xtime);      \
329 +       if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra))            \
330 +               ext4_decode_extra_time(&(einode)->xtime,                       \
331 +                                      raw_inode->xtime ## _extra);            \
332 +} while (0)
334  #if defined(__KERNEL__) || defined(__linux__)
335  #define i_reserved1    osd1.linux1.l_i_reserved1
336  #define i_frag         osd2.linux2.l_i_frag
337 @@ -539,6 +603,13 @@
338         return container_of(inode, struct ext4_inode_info, vfs_inode);
341 +static inline struct timespec ext4_current_time(struct inode *inode)
343 +       return (inode->i_sb->s_time_gran < NSEC_PER_SEC) ?
344 +               current_fs_time(inode->i_sb) : CURRENT_TIME_SEC;
348  static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
350         return ino == EXT4_ROOT_INO ||
351 @@ -609,6 +680,7 @@
352  #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
353  #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
354  #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
355 +#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE     0x0040
357  #define EXT4_FEATURE_INCOMPAT_COMPRESSION      0x0001
358  #define EXT4_FEATURE_INCOMPAT_FILETYPE         0x0002
359 @@ -626,6 +698,7 @@
360                                          EXT4_FEATURE_INCOMPAT_64BIT)
361  #define EXT4_FEATURE_RO_COMPAT_SUPP    (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
362                                          EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \
363 +                                        EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \
364                                          EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
366  /*
367 Index: linux-2.6.22-rc4/include/linux/ext4_fs_i.h
368 ===================================================================
369 --- linux-2.6.22-rc4.orig/include/linux/ext4_fs_i.h     2007-06-11 17:22:15.000000000 -0700
370 +++ linux-2.6.22-rc4/include/linux/ext4_fs_i.h  2007-06-11 17:39:05.000000000 -0700
371 @@ -153,6 +153,7 @@
373         unsigned long i_ext_generation;
374         struct ext4_ext_cache i_cached_extent;
375 +       struct timespec i_crtime;
376  };
378  #endif /* _LINUX_EXT4_FS_I */
379 Index: linux-2.6.22-rc4/include/linux/ext4_fs_sb.h
380 ===================================================================
381 --- linux-2.6.22-rc4.orig/include/linux/ext4_fs_sb.h    2007-06-11 17:28:15.000000000 -0700
382 +++ linux-2.6.22-rc4/include/linux/ext4_fs_sb.h 2007-06-11 17:39:05.000000000 -0700
383 @@ -79,6 +79,7 @@
384         char *s_qf_names[MAXQUOTAS];            /* Names of quota files with journalled quota */
385         int s_jquota_fmt;                       /* Format of quota to use */
386  #endif
387 +       unsigned int s_want_extra_isize; /* New inodes should reserve # bytes */
389  #ifdef EXTENTS_STATS
390         /* ext4 extents stats */