X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_vfs_multi.c;h=de3dd75988ef7de715fd80ec28ff6b96e501a903;hp=65404343713798010b0ed7151217c25aee6c95cc;hb=3439fa4e60dd9799766b2c101f799ed9e565b632;hpb=9ec94eea1865dfb884640c4db487d6855f801107 diff --git a/yaffs_vfs_multi.c b/yaffs_vfs_multi.c index 6540434..de3dd75 100644 --- a/yaffs_vfs_multi.c +++ b/yaffs_vfs_multi.c @@ -1,8 +1,7 @@ /* * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. * - * Copyright (C) 2002-2011 Aleph One Ltd. - * for Toby Churchill Ltd and Brightstar Engineering + * Copyright (C) 2002-2018 Aleph One Ltd. * * Created by Charles Manning * Acknowledgements: @@ -56,7 +55,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 +240,39 @@ 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 #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)) +#define PAGE_CACHE_SIZE PAGE_SIZE +#define PAGE_CACHE_SHIFT PAGE_SHIFT +#define Y_GET_DENTRY(f) ((f)->f_path.dentry) +#define page_cache_release put_page +#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 #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 +298,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 +504,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 +522,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 +614,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 +626,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 +750,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 +799,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, 8, 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 +905,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 +939,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 +973,16 @@ static int yaffs_setxattr(struct dentry *dentry, const char *name, return error; } +#ifdef YAFFS_NEW_XATTR +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 +1030,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 +1058,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 +1093,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 +1132,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 +1178,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 +1574,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 +1668,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 +1803,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); @@ -1729,8 +1816,10 @@ static int yaffs_iterate(struct file *f, struct dir_context *dc) goto out; } - if (!dir_emit_dots(f, dc)) + if (!dir_emit_dots(f, dc)) { + yaffs_gross_unlock(dev); return 0; + } curoffs = 1; @@ -1780,14 +1869,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 +3338,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 +3688,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 +3729,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);