Clean up some version dependencies
[yaffs2.git] / yaffs_vfs_multi.c
index 65404343713798010b0ed7151217c25aee6c95cc..e2f002e0cac9020f43d425d582d6e486d21ce503 100644 (file)
@@ -56,7 +56,8 @@
 #define YAFFS_HAS_EVICT_INODE
 #endif
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13)) && \
+    (LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0))
 #define YAFFS_NEW_FOLLOW_LINK 1
 #else
 #define YAFFS_NEW_FOLLOW_LINK 0
@@ -240,16 +241,42 @@ MODULE_PARM(yaffs_gc_control, "i");
 #define YAFFS_USE_DIR_ITERATE
 #endif
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0))
+#define YAFFS_USE_XATTR
+#endif
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
 #define YAFFS_NEW_PROCFS
 #include <linux/seq_file.h>
 #endif
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+#define PAGE_CACHE_SIZE PAGE_SIZE
+#define PAGE_CACHE_SHIFT PAGE_SHIFT
+#define Y_GET_DENTRY(f) ((f)->f_path.dentry)
+#define YAFFS_NEW_XATTR 1
+#define YAFFS_NEW_GET_LINK 1
+#else
+#define Y_GET_DENTRY(f) ((f)->f_dentry)
+#define YAFFS_NEW_XATTR 0
+#define YAFFS_NEW_GET_LINK 0
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
+#define page_cache_release put_page
+#endif
 
 #define update_dir_time(dir) do {\
                        (dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
                } while (0)
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0))
+static inline int setattr_prepare(struct dentry *dentry, struct iattr *attr)
+{
+       return inode_change_ok(dentry->d_inode, attr);
+}
+#endif
+
 static void yaffs_fill_inode_from_obj(struct inode *inode,
                                      struct yaffs_obj *obj);
 
@@ -275,15 +302,15 @@ static int yaffs_readpage_nolock(struct file *f, struct page *pg)
        struct yaffs_obj *obj;
        unsigned char *pg_buf;
        int ret;
-       loff_t pos = ((loff_t) pg->index) << PAGE_CACHE_SHIFT;
+       loff_t pos = ((loff_t) pg->index) << PAGE_SHIFT;
        struct yaffs_dev *dev;
 
        yaffs_trace(YAFFS_TRACE_OS,
                "yaffs_readpage_nolock at %lld, size %08x",
                (long long)pos,
-               (unsigned)PAGE_CACHE_SIZE);
+               (unsigned)PAGE_SIZE);
 
-       obj = yaffs_dentry_to_obj(f->f_dentry);
+       obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f));
 
        dev = obj->my_dev;
 
@@ -481,7 +508,7 @@ static ssize_t yaffs_hold_space(struct file *f)
 
        int n_free_chunks;
 
-       obj = yaffs_dentry_to_obj(f->f_dentry);
+       obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f));
 
        dev = obj->my_dev;
 
@@ -499,7 +526,7 @@ static void yaffs_release_space(struct file *f)
        struct yaffs_obj *obj;
        struct yaffs_dev *dev;
 
-       obj = yaffs_dentry_to_obj(f->f_dentry);
+       obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f));
 
        dev = obj->my_dev;
 
@@ -591,7 +618,7 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
        struct inode *inode;
        struct yaffs_dev *dev;
 
-       obj = yaffs_dentry_to_obj(f->f_dentry);
+       obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f));
 
        if (!obj) {
                yaffs_trace(YAFFS_TRACE_OS,
@@ -603,7 +630,7 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
 
        yaffs_gross_lock(dev);
 
-       inode = f->f_dentry->d_inode;
+       inode = Y_GET_DENTRY(f)->d_inode;
 
        if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
                ipos = inode->i_size;
@@ -727,7 +754,7 @@ static int yaffs_file_flush(struct file *file, fl_owner_t id)
 static int yaffs_file_flush(struct file *file)
 #endif
 {
-       struct yaffs_obj *obj = yaffs_dentry_to_obj(file->f_dentry);
+       struct yaffs_obj *obj = yaffs_dentry_to_obj(Y_GET_DENTRY(file));
 
        struct yaffs_dev *dev = obj->my_dev;
 
@@ -776,15 +803,28 @@ static int yaffs_sync_object(struct file *file, struct dentry *dentry,
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
 static const struct file_operations yaffs_file_operations = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
+       .read = new_sync_read,
+       .write = new_sync_write,
+#endif
+       .read_iter = generic_file_read_iter,
+       .write_iter = generic_file_write_iter,
+#else
        .read = do_sync_read,
        .write = do_sync_write,
        .aio_read = generic_file_aio_read,
        .aio_write = generic_file_aio_write,
+#endif
        .mmap = generic_file_mmap,
        .flush = yaffs_file_flush,
        .fsync = yaffs_sync_object,
        .splice_read = generic_file_splice_read,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+       .splice_write = iter_file_splice_write,
+#else
        .splice_write = generic_file_splice_write,
+#endif
        .llseek = generic_file_llseek,
 };
 
@@ -869,7 +909,7 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
 #endif
 
        if (error == 0)
-               error = inode_change_ok(inode, attr);
+               error = setattr_prepare(dentry, attr);
        if (error == 0) {
                int result;
                if (!error) {
@@ -903,10 +943,17 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
        return error;
 }
 
+#ifdef YAFFS_USE_XATTR
+#if (YAFFS_NEW_XATTR > 0)
+static int yaffs_setxattr(struct dentry *dentry, struct inode *inode,
+               const char *name, const void *value, size_t size, int flags)
+{
+#else
 static int yaffs_setxattr(struct dentry *dentry, const char *name,
                   const void *value, size_t size, int flags)
 {
        struct inode *inode = dentry->d_inode;
+#endif
        int error = 0;
        struct yaffs_dev *dev;
        struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
@@ -930,10 +977,16 @@ static int yaffs_setxattr(struct dentry *dentry, const char *name,
        return error;
 }
 
+#if (YAFFS_NEW_XATTR > 0)
+static ssize_t yaffs_getxattr(struct dentry * dentry, struct inode *inode,
+       const char *name, void *buff, size_t size)
+{
+#else
 static ssize_t yaffs_getxattr(struct dentry * dentry, const char *name,
                        void *buff, size_t size)
 {
        struct inode *inode = dentry->d_inode;
+#endif
        int error = 0;
        struct yaffs_dev *dev;
        struct yaffs_obj *obj = yaffs_inode_to_obj(inode);
@@ -981,6 +1034,7 @@ static int yaffs_removexattr(struct dentry *dentry, const char *name)
 
        return error;
 }
+#endif
 
 static ssize_t yaffs_listxattr(struct dentry * dentry, char *buff, size_t size)
 {
@@ -1008,10 +1062,12 @@ static ssize_t yaffs_listxattr(struct dentry * dentry, char *buff, size_t size)
 
 static const struct inode_operations yaffs_file_inode_operations = {
        .setattr = yaffs_setattr,
+#ifdef YAFFS_USE_XATTR
        .setxattr = yaffs_setxattr,
        .getxattr = yaffs_getxattr,
-       .listxattr = yaffs_listxattr,
        .removexattr = yaffs_removexattr,
+#endif
+       .listxattr = yaffs_listxattr,
 };
 
 
@@ -1041,6 +1097,7 @@ static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
        return ret;
 }
 
+#if (YAFFS_NEW_GET_LINK == 0)
 #if (YAFFS_NEW_FOLLOW_LINK == 1)
 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
@@ -1079,7 +1136,28 @@ out:
        return ret;
 #endif
 }
+#else
+static const char *yaffs_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done)
+{
+       unsigned char *alias;
+       struct yaffs_dev *dev;
 
+       if (!dentry)
+               return ERR_PTR(-ECHILD);
+
+       dev = yaffs_dentry_to_obj(dentry)->my_dev;
+
+       yaffs_gross_lock(dev);
+
+       alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry));
+       yaffs_gross_unlock(dev);
+
+       if (!alias)
+               return ERR_PTR(-ENOMEM);
+       set_delayed_call(done, kfree_link, alias);
+       return alias;
+}
+#endif
 
 #ifdef YAFFS_HAS_PUT_INODE
 
@@ -1104,15 +1182,21 @@ void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias)
 
 static const struct inode_operations yaffs_symlink_inode_operations = {
        .readlink = yaffs_readlink,
+#if (YAFFS_NEW_GET_LINK == 1)
+       .get_link = yaffs_get_link,
+#else
        .follow_link = yaffs_follow_link,
+#endif
 #if (YAFFS_NEW_FOLLOW_LINK == 1)
        .put_link = yaffs_put_link,
 #endif
        .setattr = yaffs_setattr,
+#ifdef YAFFS_USE_XATTR
        .setxattr = yaffs_setxattr,
        .getxattr = yaffs_getxattr,
-       .listxattr = yaffs_listxattr,
        .removexattr = yaffs_removexattr,
+#endif
+       .listxattr = yaffs_listxattr,
 };
 
 #ifdef YAFFS_USE_OWN_IGET
@@ -1494,8 +1578,13 @@ static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
  *
  * NB: POSIX says you can rename an object over an old object of the same name
  */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
+static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
+                       struct inode *new_dir, struct dentry *new_dentry, unsigned int unused)
+#else
 static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        struct inode *new_dir, struct dentry *new_dentry)
+#endif
 {
        struct yaffs_dev *dev;
        int ret_val = YAFFS_FAIL;
@@ -1583,10 +1672,12 @@ static const struct inode_operations yaffs_dir_inode_operations = {
        .mknod = yaffs_mknod,
        .rename = yaffs_rename,
        .setattr = yaffs_setattr,
+       .listxattr = yaffs_listxattr,
+#ifdef YAFFS_USE_XATTR
        .setxattr = yaffs_setxattr,
        .getxattr = yaffs_getxattr,
-       .listxattr = yaffs_listxattr,
        .removexattr = yaffs_removexattr,
+#endif
 };
 
 /*-----------------------------------------------------------------*/
@@ -1716,7 +1807,7 @@ static int yaffs_iterate(struct file *f, struct dir_context *dc)
 
        char name[YAFFS_MAX_NAME_LENGTH + 1];
 
-       obj = yaffs_dentry_to_obj(f->f_dentry);
+       obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f));
        dev = obj->my_dev;
 
        yaffs_gross_lock(dev);
@@ -1780,14 +1871,14 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
        struct yaffs_obj *obj;
        struct yaffs_dev *dev;
        struct yaffs_search_context *sc;
-       struct inode *inode = f->f_dentry->d_inode;
+       struct inode *inode = Y_GET_DENTRY(f)->d_inode;
        unsigned long offset, curoffs;
        struct yaffs_obj *l;
        int ret_val = 0;
 
        char name[YAFFS_MAX_NAME_LENGTH + 1];
 
-       obj = yaffs_dentry_to_obj(f->f_dentry);
+       obj = yaffs_dentry_to_obj(Y_GET_DENTRY(f));
        dev = obj->my_dev;
 
        yaffs_gross_lock(dev);
@@ -3249,9 +3340,7 @@ static int yaffs_proc_read(char *page,
        /* Print header first */
        if (step == 0)
                buf +=
-                   sprintf(buf,
-                           "Multi-version YAFFS built:" __DATE__ " " __TIME__
-                           "\n");
+                   sprintf(buf, "Multi-version YAFFS\n");
        else if (step == 1)
                buf += sprintf(buf, "\n");
        else {
@@ -3601,7 +3690,7 @@ static int __init init_yaffs_fs(void)
        struct file_system_to_install *fsinst;
 
        yaffs_trace(YAFFS_TRACE_ALWAYS,
-               "yaffs built " __DATE__ " " __TIME__ " Installing.");
+               "yaffs Installing.");
 
        mutex_init(&yaffs_context_lock);
 
@@ -3642,7 +3731,7 @@ static void __exit exit_yaffs_fs(void)
        struct file_system_to_install *fsinst;
 
        yaffs_trace(YAFFS_TRACE_ALWAYS,
-               "yaffs built " __DATE__ " " __TIME__ " removing.");
+               "yaffs removing.");
 
        remove_proc_entry("yaffs", YPROC_ROOT);