]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/gfs2/inode.c
fat: Fix _fat_bmap() race
[linux-2.6-omap-h63xx.git] / fs / gfs2 / inode.c
index 8b0806a3294863392c914aa262b2a4cb08f4c98e..7cee695fa44163f378293945514b1e4a9bbfd084 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/crc32.h>
 #include <linux/lm_interface.h>
 #include <linux/security.h>
+#include <linux/time.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -249,6 +250,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
 {
        struct gfs2_dinode_host *di = &ip->i_di;
        const struct gfs2_dinode *str = buf;
+       struct timespec atime;
        u16 height, depth;
 
        if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
@@ -275,8 +277,10 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
        di->di_size = be64_to_cpu(str->di_size);
        i_size_write(&ip->i_inode, di->di_size);
        gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
-       ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime);
-       ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
+       atime.tv_sec = be64_to_cpu(str->di_atime);
+       atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
+       if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0)
+               ip->i_inode.i_atime = atime;
        ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
        ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
        ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
@@ -1033,13 +1037,11 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
 
        if (bh)
                brelse(bh);
-       if (!inode)
-               return ERR_PTR(-ENOMEM);
        return inode;
 
 fail_gunlock2:
        gfs2_glock_dq_uninit(ghs + 1);
-       if (inode)
+       if (inode && !IS_ERR(inode))
                iput(inode);
 fail_gunlock:
        gfs2_glock_dq(ghs);
@@ -1140,54 +1142,6 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
        return 0;
 }
 
-/*
- * gfs2_ok_to_move - check if it's ok to move a directory to another directory
- * @this: move this
- * @to: to here
- *
- * Follow @to back to the root and make sure we don't encounter @this
- * Assumes we already hold the rename lock.
- *
- * Returns: errno
- */
-
-int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
-{
-       struct inode *dir = &to->i_inode;
-       struct super_block *sb = dir->i_sb;
-       struct inode *tmp;
-       struct qstr dotdot;
-       int error = 0;
-
-       gfs2_str2qstr(&dotdot, "..");
-
-       igrab(dir);
-
-       for (;;) {
-               if (dir == &this->i_inode) {
-                       error = -EINVAL;
-                       break;
-               }
-               if (dir == sb->s_root->d_inode) {
-                       error = 0;
-                       break;
-               }
-
-               tmp = gfs2_lookupi(dir, &dotdot, 1);
-               if (IS_ERR(tmp)) {
-                       error = PTR_ERR(tmp);
-                       break;
-               }
-
-               iput(dir);
-               dir = tmp;
-       }
-
-       iput(dir);
-
-       return error;
-}
-
 /**
  * gfs2_readlinki - return the contents of a symlink
  * @ip: the symlink's inode
@@ -1207,8 +1161,8 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len)
        unsigned int x;
        int error;
 
-       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh);
-       error = gfs2_glock_nq_atime(&i_gh);
+       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh);
+       error = gfs2_glock_nq(&i_gh);
        if (error) {
                gfs2_holder_uninit(&i_gh);
                return error;
@@ -1243,101 +1197,6 @@ out:
        return error;
 }
 
-/**
- * gfs2_glock_nq_atime - Acquire a hold on an inode's glock, and
- *       conditionally update the inode's atime
- * @gh: the holder to acquire
- *
- * Tests atime (access time) for gfs2_read, gfs2_readdir and gfs2_mmap
- * Update if the difference between the current time and the inode's current
- * atime is greater than an interval specified at mount.
- *
- * Returns: errno
- */
-
-int gfs2_glock_nq_atime(struct gfs2_holder *gh)
-{
-       struct gfs2_glock *gl = gh->gh_gl;
-       struct gfs2_sbd *sdp = gl->gl_sbd;
-       struct gfs2_inode *ip = gl->gl_object;
-       s64 quantum = gfs2_tune_get(sdp, gt_atime_quantum);
-       unsigned int state;
-       int flags;
-       int error;
-       struct timespec tv = CURRENT_TIME;
-
-       if (gfs2_assert_warn(sdp, gh->gh_flags & GL_ATIME) ||
-           gfs2_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) ||
-           gfs2_assert_warn(sdp, gl->gl_ops == &gfs2_inode_glops))
-               return -EINVAL;
-
-       state = gh->gh_state;
-       flags = gh->gh_flags;
-
-       error = gfs2_glock_nq(gh);
-       if (error)
-               return error;
-
-       if (test_bit(SDF_NOATIME, &sdp->sd_flags) ||
-           (sdp->sd_vfs->s_flags & MS_RDONLY))
-               return 0;
-
-       if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
-               gfs2_glock_dq(gh);
-               gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY,
-                                  gh);
-               error = gfs2_glock_nq(gh);
-               if (error)
-                       return error;
-
-               /* Verify that atime hasn't been updated while we were
-                  trying to get exclusive lock. */
-
-               tv = CURRENT_TIME;
-               if (tv.tv_sec - ip->i_inode.i_atime.tv_sec >= quantum) {
-                       struct buffer_head *dibh;
-                       struct gfs2_dinode *di;
-
-                       error = gfs2_trans_begin(sdp, RES_DINODE, 0);
-                       if (error == -EROFS)
-                               return 0;
-                       if (error)
-                               goto fail;
-
-                       error = gfs2_meta_inode_buffer(ip, &dibh);
-                       if (error)
-                               goto fail_end_trans;
-
-                       ip->i_inode.i_atime = tv;
-
-                       gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-                       di = (struct gfs2_dinode *)dibh->b_data;
-                       di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec);
-                       di->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec);
-                       brelse(dibh);
-
-                       gfs2_trans_end(sdp);
-               }
-
-               /* If someone else has asked for the glock,
-                  unlock and let them have it. Then reacquire
-                  in the original state. */
-               if (gfs2_glock_is_blocking(gl)) {
-                       gfs2_glock_dq(gh);
-                       gfs2_holder_reinit(state, flags, gh);
-                       return gfs2_glock_nq(gh);
-               }
-       }
-
-       return 0;
-
-fail_end_trans:
-       gfs2_trans_end(sdp);
-fail:
-       gfs2_glock_dq(gh);
-       return error;
-}
-
 static int
 __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
 {