Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[cascardo/linux.git] / fs / fat / namei_vfat.c
index 6ccdf3f..6a7152d 100644 (file)
 #include <linux/namei.h>
 #include "fat.h"
 
+static inline unsigned long vfat_d_version(struct dentry *dentry)
+{
+       return (unsigned long) dentry->d_fsdata;
+}
+
+static inline void vfat_d_version_set(struct dentry *dentry,
+                                     unsigned long version)
+{
+       dentry->d_fsdata = (void *) version;
+}
+
 /*
  * If new entry was created in the parent, it could create the 8.3
  * alias (the shortname of logname).  So, the parent may have the
@@ -33,7 +44,7 @@ static int vfat_revalidate_shortname(struct dentry *dentry)
 {
        int ret = 1;
        spin_lock(&dentry->d_lock);
-       if (dentry->d_time != d_inode(dentry->d_parent)->i_version)
+       if (vfat_d_version(dentry) != d_inode(dentry->d_parent)->i_version)
                ret = 0;
        spin_unlock(&dentry->d_lock);
        return ret;
@@ -138,10 +149,10 @@ static int vfat_hashi(const struct dentry *dentry, struct qstr *qstr)
 /*
  * Case insensitive compare of two vfat names.
  */
-static int vfat_cmpi(const struct dentry *parent, const struct dentry *dentry,
+static int vfat_cmpi(const struct dentry *dentry,
                unsigned int len, const char *str, const struct qstr *name)
 {
-       struct nls_table *t = MSDOS_SB(parent->d_sb)->nls_io;
+       struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io;
        unsigned int alen, blen;
 
        /* A filename cannot end in '.' or we treat it like it has none */
@@ -157,7 +168,7 @@ static int vfat_cmpi(const struct dentry *parent, const struct dentry *dentry,
 /*
  * Case sensitive compare of two vfat names.
  */
-static int vfat_cmp(const struct dentry *parent, const struct dentry *dentry,
+static int vfat_cmp(const struct dentry *dentry,
                unsigned int len, const char *str, const struct qstr *name)
 {
        unsigned int alen, blen;
@@ -652,8 +663,8 @@ out_free:
        return err;
 }
 
-static int vfat_add_entry(struct inode *dir, struct qstr *qname, int is_dir,
-                         int cluster, struct timespec *ts,
+static int vfat_add_entry(struct inode *dir, const struct qstr *qname,
+                         int is_dir, int cluster, struct timespec *ts,
                          struct fat_slot_info *sinfo)
 {
        struct msdos_dir_slot *slots;
@@ -688,7 +699,7 @@ cleanup:
        return err;
 }
 
-static int vfat_find(struct inode *dir, struct qstr *qname,
+static int vfat_find(struct inode *dir, const struct qstr *qname,
                     struct fat_slot_info *sinfo)
 {
        unsigned int len = vfat_striptail_len(qname);
@@ -759,7 +770,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
 out:
        mutex_unlock(&MSDOS_SB(sb)->s_lock);
        if (!inode)
-               dentry->d_time = dir->i_version;
+               vfat_d_version_set(dentry, dir->i_version);
        return d_splice_alias(inode, dentry);
 error:
        mutex_unlock(&MSDOS_SB(sb)->s_lock);
@@ -777,7 +788,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
 
        mutex_lock(&MSDOS_SB(sb)->s_lock);
 
-       ts = CURRENT_TIME_SEC;
+       ts = current_time(dir);
        err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo);
        if (err)
                goto out;
@@ -821,9 +832,9 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
        drop_nlink(dir);
 
        clear_nlink(inode);
-       inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
+       inode->i_mtime = inode->i_atime = current_time(inode);
        fat_detach(inode);
-       dentry->d_time = dir->i_version;
+       vfat_d_version_set(dentry, dir->i_version);
 out:
        mutex_unlock(&MSDOS_SB(sb)->s_lock);
 
@@ -847,9 +858,9 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
        if (err)
                goto out;
        clear_nlink(inode);
-       inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
+       inode->i_mtime = inode->i_atime = current_time(inode);
        fat_detach(inode);
-       dentry->d_time = dir->i_version;
+       vfat_d_version_set(dentry, dir->i_version);
 out:
        mutex_unlock(&MSDOS_SB(sb)->s_lock);
 
@@ -866,7 +877,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 
        mutex_lock(&MSDOS_SB(sb)->s_lock);
 
-       ts = CURRENT_TIME_SEC;
+       ts = current_time(dir);
        cluster = fat_alloc_new_dir(dir, &ts);
        if (cluster < 0) {
                err = cluster;
@@ -903,7 +914,8 @@ out:
 }
 
 static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
-                      struct inode *new_dir, struct dentry *new_dentry)
+                      struct inode *new_dir, struct dentry *new_dentry,
+                      unsigned int flags)
 {
        struct buffer_head *dotdot_bh;
        struct msdos_dir_entry *dotdot_de;
@@ -914,6 +926,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
        int err, is_dir, update_dotdot, corrupt = 0;
        struct super_block *sb = old_dir->i_sb;
 
+       if (flags & ~RENAME_NOREPLACE)
+               return -EINVAL;
+
        old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
        old_inode = d_inode(old_dentry);
        new_inode = d_inode(new_dentry);
@@ -931,7 +946,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
                }
        }
 
-       ts = CURRENT_TIME_SEC;
+       ts = current_time(old_dir);
        if (new_inode) {
                if (is_dir) {
                        err = fat_dir_empty(new_inode);