aboutsummaryrefslogtreecommitdiffstats
path: root/fs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/inode.c')
-rw-r--r--fs/inode.c77
1 files changed, 59 insertions, 18 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 826fb0b9d1c3..d06d6d268de9 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -17,6 +17,7 @@
17#include <linux/hash.h> 17#include <linux/hash.h>
18#include <linux/swap.h> 18#include <linux/swap.h>
19#include <linux/security.h> 19#include <linux/security.h>
20#include <linux/ima.h>
20#include <linux/pagemap.h> 21#include <linux/pagemap.h>
21#include <linux/cdev.h> 22#include <linux/cdev.h>
22#include <linux/bootmem.h> 23#include <linux/bootmem.h>
@@ -147,13 +148,13 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
147 inode->i_cdev = NULL; 148 inode->i_cdev = NULL;
148 inode->i_rdev = 0; 149 inode->i_rdev = 0;
149 inode->dirtied_when = 0; 150 inode->dirtied_when = 0;
150 if (security_inode_alloc(inode)) { 151
151 if (inode->i_sb->s_op->destroy_inode) 152 if (security_inode_alloc(inode))
152 inode->i_sb->s_op->destroy_inode(inode); 153 goto out_free_inode;
153 else 154
154 kmem_cache_free(inode_cachep, (inode)); 155 /* allocate and initialize an i_integrity */
155 return NULL; 156 if (ima_inode_alloc(inode))
156 } 157 goto out_free_security;
157 158
158 spin_lock_init(&inode->i_lock); 159 spin_lock_init(&inode->i_lock);
159 lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key); 160 lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
@@ -189,6 +190,15 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
189 inode->i_mapping = mapping; 190 inode->i_mapping = mapping;
190 191
191 return inode; 192 return inode;
193
194out_free_security:
195 security_inode_free(inode);
196out_free_inode:
197 if (inode->i_sb->s_op->destroy_inode)
198 inode->i_sb->s_op->destroy_inode(inode);
199 else
200 kmem_cache_free(inode_cachep, (inode));
201 return NULL;
192} 202}
193EXPORT_SYMBOL(inode_init_always); 203EXPORT_SYMBOL(inode_init_always);
194 204
@@ -284,7 +294,7 @@ void clear_inode(struct inode *inode)
284 BUG_ON(!(inode->i_state & I_FREEING)); 294 BUG_ON(!(inode->i_state & I_FREEING));
285 BUG_ON(inode->i_state & I_CLEAR); 295 BUG_ON(inode->i_state & I_CLEAR);
286 inode_sync_wait(inode); 296 inode_sync_wait(inode);
287 DQUOT_DROP(inode); 297 vfs_dq_drop(inode);
288 if (inode->i_sb->s_op->clear_inode) 298 if (inode->i_sb->s_op->clear_inode)
289 inode->i_sb->s_op->clear_inode(inode); 299 inode->i_sb->s_op->clear_inode(inode);
290 if (S_ISBLK(inode->i_mode) && inode->i_bdev) 300 if (S_ISBLK(inode->i_mode) && inode->i_bdev)
@@ -356,6 +366,8 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
356 if (tmp == head) 366 if (tmp == head)
357 break; 367 break;
358 inode = list_entry(tmp, struct inode, i_sb_list); 368 inode = list_entry(tmp, struct inode, i_sb_list);
369 if (inode->i_state & I_NEW)
370 continue;
359 invalidate_inode_buffers(inode); 371 invalidate_inode_buffers(inode);
360 if (!atomic_read(&inode->i_count)) { 372 if (!atomic_read(&inode->i_count)) {
361 list_move(&inode->i_list, dispose); 373 list_move(&inode->i_list, dispose);
@@ -1158,7 +1170,7 @@ void generic_delete_inode(struct inode *inode)
1158 if (op->delete_inode) { 1170 if (op->delete_inode) {
1159 void (*delete)(struct inode *) = op->delete_inode; 1171 void (*delete)(struct inode *) = op->delete_inode;
1160 if (!is_bad_inode(inode)) 1172 if (!is_bad_inode(inode))
1161 DQUOT_INIT(inode); 1173 vfs_dq_init(inode);
1162 /* Filesystems implementing their own 1174 /* Filesystems implementing their own
1163 * s_op->delete_inode are required to call 1175 * s_op->delete_inode are required to call
1164 * truncate_inode_pages and clear_inode() 1176 * truncate_inode_pages and clear_inode()
@@ -1290,6 +1302,40 @@ sector_t bmap(struct inode * inode, sector_t block)
1290} 1302}
1291EXPORT_SYMBOL(bmap); 1303EXPORT_SYMBOL(bmap);
1292 1304
1305/*
1306 * With relative atime, only update atime if the previous atime is
1307 * earlier than either the ctime or mtime or if at least a day has
1308 * passed since the last atime update.
1309 */
1310static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
1311 struct timespec now)
1312{
1313
1314 if (!(mnt->mnt_flags & MNT_RELATIME))
1315 return 1;
1316 /*
1317 * Is mtime younger than atime? If yes, update atime:
1318 */
1319 if (timespec_compare(&inode->i_mtime, &inode->i_atime) >= 0)
1320 return 1;
1321 /*
1322 * Is ctime younger than atime? If yes, update atime:
1323 */
1324 if (timespec_compare(&inode->i_ctime, &inode->i_atime) >= 0)
1325 return 1;
1326
1327 /*
1328 * Is the previous atime value older than a day? If yes,
1329 * update atime:
1330 */
1331 if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= 24*60*60)
1332 return 1;
1333 /*
1334 * Good, we can skip the atime update:
1335 */
1336 return 0;
1337}
1338
1293/** 1339/**
1294 * touch_atime - update the access time 1340 * touch_atime - update the access time
1295 * @mnt: mount the inode is accessed on 1341 * @mnt: mount the inode is accessed on
@@ -1317,17 +1363,12 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
1317 goto out; 1363 goto out;
1318 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) 1364 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
1319 goto out; 1365 goto out;
1320 if (mnt->mnt_flags & MNT_RELATIME) {
1321 /*
1322 * With relative atime, only update atime if the previous
1323 * atime is earlier than either the ctime or mtime.
1324 */
1325 if (timespec_compare(&inode->i_mtime, &inode->i_atime) < 0 &&
1326 timespec_compare(&inode->i_ctime, &inode->i_atime) < 0)
1327 goto out;
1328 }
1329 1366
1330 now = current_fs_time(inode->i_sb); 1367 now = current_fs_time(inode->i_sb);
1368
1369 if (!relatime_need_update(mnt, inode, now))
1370 goto out;
1371
1331 if (timespec_equal(&inode->i_atime, &now)) 1372 if (timespec_equal(&inode->i_atime, &now))
1332 goto out; 1373 goto out;
1333 1374