From: Charles Manning Date: Wed, 18 Jun 2014 02:21:03 +0000 (+1200) Subject: Update to support Linux 3.14/3.15 X-Git-Tag: aleph1-release~40 X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=commitdiff_plain;h=4e188b08c5531f99f73383a85251e03a1e667b26 Update to support Linux 3.14/3.15 Thanks to Andre Renaud for doing some of this. Signed-off-by: Charles Manning --- diff --git a/yaffs_attribs.c b/yaffs_attribs.c index 3d778f2..711941f 100644 --- a/yaffs_attribs.c +++ b/yaffs_attribs.c @@ -14,6 +14,14 @@ #include "yaffs_guts.h" #include "yaffs_attribs.h" +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) +#define IATTR_UID ia_uid +#define IATTR_GID ia_gid +#else +#define IATTR_UID ia_uid.val +#define IATTR_GID ia_gid.val +#endif + void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh) { obj->yst_uid = oh->yst_uid; @@ -77,9 +85,9 @@ int yaffs_set_attribs(struct yaffs_obj *obj, struct iattr *attr) if (valid & ATTR_MODE) obj->yst_mode = attr->ia_mode; if (valid & ATTR_UID) - obj->yst_uid = attr->ia_uid; + obj->yst_uid = attr->IATTR_UID; if (valid & ATTR_GID) - obj->yst_gid = attr->ia_gid; + obj->yst_gid = attr->IATTR_GID; if (valid & ATTR_ATIME) obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime); @@ -103,9 +111,9 @@ int yaffs_get_attribs(struct yaffs_obj *obj, struct iattr *attr) attr->ia_mode = obj->yst_mode; valid |= ATTR_MODE; - attr->ia_uid = obj->yst_uid; + attr->IATTR_UID = obj->yst_uid; valid |= ATTR_UID; - attr->ia_gid = obj->yst_gid; + attr->IATTR_GID = obj->yst_gid; valid |= ATTR_GID; Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime; diff --git a/yaffs_mtdif_multi.c b/yaffs_mtdif_multi.c index 7ae63c5..7c01461 100644 --- a/yaffs_mtdif_multi.c +++ b/yaffs_mtdif_multi.c @@ -22,12 +22,14 @@ #include "linux/kernel.h" #include "linux/version.h" #include "linux/types.h" +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) +#include "uapi/linux/major.h" +#endif #include "yaffs_trace.h" #include "yaffs_guts.h" #include "yaffs_linux.h" - #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) #define MTD_OPS_AUTO_OOB MTD_OOB_AUTO #endif diff --git a/yaffs_vfs_multi.c b/yaffs_vfs_multi.c index f767315..76bc1db 100644 --- a/yaffs_vfs_multi.c +++ b/yaffs_vfs_multi.c @@ -236,6 +236,15 @@ MODULE_PARM(yaffs_gc_control, "i"); #define Y_CLEAR_INODE(i) end_writeback(i) #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) +#define YAFFS_USE_DIR_ITERATE +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0)) +#define YAFFS_NEW_PROCFS +#include +#endif + #define update_dir_time(dir) do {\ (dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \ @@ -1023,7 +1032,11 @@ static int yaffs_readlink(struct dentry *dentry, char __user * buffer, if (!alias) return -ENOMEM; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0) ret = vfs_readlink(dentry, buffer, buflen, alias); +#else + ret = readlink_copy(buffer, buflen, alias); +#endif kfree(alias); return ret; } @@ -1206,6 +1219,23 @@ struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, #define YCRED(x) (x->cred) #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) +#define YPROC_uid(p) (YCRED(p)->fsuid) +#define YPROC_gid(p) (YCRED(p)->fsgid) +#define EXTRACT_gid(x) x +#define EXTRACT_uid(x) x +#define MAKE_gid(x) x +#define MAKE_uid(x) x +#else +#define YPROC_uid(p) from_kuid(&init_user_ns, YCRED(p)->fsuid) +#define YPROC_gid(p) from_kgid(&init_user_ns, YCRED(p)->fsgid) +#define EXTRACT_gid(x) from_kgid(&init_user_ns, x) +#define EXTRACT_uid(x) from_kuid(&init_user_ns, x) +#define MAKE_gid(x) make_kgid(&init_user_ns, x) +#define MAKE_uid(x) make_kuid(&init_user_ns, x) +#endif + + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) static int yaffs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) @@ -1225,9 +1255,9 @@ static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, struct yaffs_obj *parent = yaffs_inode_to_obj(dir); int error = -ENOSPC; - uid_t uid = YCRED(current)->fsuid; + uid_t uid = YPROC_uid(current); gid_t gid = - (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid; + (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current); if ((dir->i_mode & S_ISGID) && S_ISDIR(mode)) mode |= S_ISGID; @@ -1424,9 +1454,9 @@ static int yaffs_symlink(struct inode *dir, struct dentry *dentry, { struct yaffs_obj *obj; struct yaffs_dev *dev; - uid_t uid = YCRED(current)->fsuid; + uid_t uid = YPROC_uid(current); gid_t gid = - (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid; + (dir->i_mode & S_ISGID) ? EXTRACT_gid(dir->i_gid) : YPROC_gid(current); yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink"); @@ -1674,6 +1704,77 @@ static void yaffs_remove_obj_callback(struct yaffs_obj *obj) /*-----------------------------------------------------------------*/ +#ifdef YAFFS_USE_DIR_ITERATE +static int yaffs_iterate(struct file *f, struct dir_context *dc) +{ + struct yaffs_obj *obj; + struct yaffs_dev *dev; + struct yaffs_search_context *sc; + unsigned long curoffs; + struct yaffs_obj *l; + int ret_val = 0; + + char name[YAFFS_MAX_NAME_LENGTH + 1]; + + obj = yaffs_dentry_to_obj(f->f_dentry); + dev = obj->my_dev; + + yaffs_gross_lock(dev); + + yaffs_dev_to_lc(dev)->readdir_process = current; + + sc = yaffs_new_search(obj); + if (!sc) { + ret_val = -ENOMEM; + goto out; + } + + if (!dir_emit_dots(f, dc)) + return 0; + + curoffs = 1; + + while (sc->next_return) { + curoffs++; + l = sc->next_return; + if (curoffs >= dc->pos) { + int this_inode = yaffs_get_obj_inode(l); + int this_type = yaffs_get_obj_type(l); + + yaffs_get_obj_name(l, name, YAFFS_MAX_NAME_LENGTH + 1); + yaffs_trace(YAFFS_TRACE_OS, + "yaffs_readdir: %s inode %d", + name, yaffs_get_obj_inode(l)); + + yaffs_gross_unlock(dev); + + if (!dir_emit(dc, + name, + strlen(name), + this_inode, + this_type)) { + yaffs_gross_lock(dev); + goto out; + } + + yaffs_gross_lock(dev); + + dc->pos++; + f->f_pos++; + } + yaffs_search_advance(sc); + } + +out: + yaffs_search_end(sc); + yaffs_dev_to_lc(dev)->readdir_process = NULL; + yaffs_gross_unlock(dev); + + return ret_val; +} + +#else + static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) { struct yaffs_obj *obj; @@ -1781,9 +1882,15 @@ out: return ret_val; } +#endif + static const struct file_operations yaffs_dir_operations = { .read = generic_read_dir, +#ifdef YAFFS_USE_DIR_ITERATE + .iterate = yaffs_iterate, +#else .readdir = yaffs_readdir, +#endif .fsync = yaffs_sync_object, .llseek = generic_file_llseek, }; @@ -1829,8 +1936,8 @@ static void yaffs_fill_inode_from_obj(struct inode *inode, inode->i_ino = obj->obj_id; inode->i_mode = obj->yst_mode; - inode->i_uid = obj->yst_uid; - inode->i_gid = obj->yst_gid; + inode->i_uid = MAKE_uid(obj->yst_uid); + inode->i_gid = MAKE_gid(obj->yst_gid); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)) inode->i_blksize = inode->i_sb->s_blocksize; #endif @@ -1856,7 +1963,7 @@ static void yaffs_fill_inode_from_obj(struct inode *inode, yaffs_trace(YAFFS_TRACE_OS, "yaffs_fill_inode mode %x uid %d gid %d size %lld count %d", - inode->i_mode, inode->i_uid, inode->i_gid, + inode->i_mode, obj->yst_uid, obj->yst_gid, inode->i_size, atomic_read(&inode->i_count)); switch (obj->yst_mode & S_IFMT) { @@ -3184,7 +3291,7 @@ static struct { #define MAX_MASK_NAME_LENGTH 40 static int yaffs_proc_write_trace_options(struct file *file, const char *buf, - unsigned long count, void *data) + unsigned long count) { unsigned rg = 0, mask_bitfield; char *end; @@ -3285,7 +3392,7 @@ static int yaffs_proc_write_trace_options(struct file *file, const char *buf, */ static int yaffs_proc_debug_write(struct file *file, const char *buf, - unsigned long count, void *data) + unsigned long count) { char str[100]; @@ -3297,7 +3404,7 @@ static int yaffs_proc_debug_write(struct file *file, const char *buf, struct list_head *item; memset(str, 0, sizeof(str)); - memcpy(str, buf, min(count, sizeof(str) -1)); + memcpy(str, buf, min((size_t)count, sizeof(str) -1)); cmd = str[1]; @@ -3360,12 +3467,18 @@ static int yaffs_proc_debug_write(struct file *file, const char *buf, return count; } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) static int yaffs_proc_write(struct file *file, const char *buf, - unsigned long count, void *data) + unsigned long count, void *ppos) +#else +static ssize_t yaffs_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +#endif { if (buf[0] == '.') - return yaffs_proc_debug_write(file, buf, count, data); - return yaffs_proc_write_trace_options(file, buf, count, data); + return yaffs_proc_debug_write(file, buf, count); + return yaffs_proc_write_trace_options(file, buf, count); } /* Stuff to handle installation of file systems */ @@ -3380,16 +3493,52 @@ static struct file_system_to_install fs_to_install[] = { {NULL, 0} }; -static int __init init_yaffs_fs(void) + +#ifdef YAFFS_NEW_PROCFS +static int yaffs_proc_show(struct seq_file *m, void *v) { - int error = 0; - struct file_system_to_install *fsinst; + /* FIXME: Unify in a better way? */ + char buffer[512]; + char *start; + int len; - yaffs_trace(YAFFS_TRACE_ALWAYS, - "yaffs built " __DATE__ " " __TIME__ " Installing."); + len = yaffs_proc_read(buffer, &start, 0, sizeof(buffer), NULL, NULL); + seq_puts(m, buffer); + return 0; +} - mutex_init(&yaffs_context_lock); +static int yaffs_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, yaffs_proc_show, NULL); +} +static struct file_operations procfs_ops = { + .owner = THIS_MODULE, + .open = yaffs_proc_open, + .read = seq_read, + .write = yaffs_proc_write, +}; + +static int yaffs_procfs_init(void) +{ + /* Install the proc_fs entries */ + my_proc_entry = proc_create("yaffs", + S_IRUGO | S_IFREG, + YPROC_ROOT, + &procfs_ops); + + if (my_proc_entry) { + return 0; + } else { + return -ENOMEM; + } +} + +#else + + +static int yaffs_procfs_init(void) +{ /* Install the proc_fs entries */ my_proc_entry = create_proc_entry("yaffs", S_IRUGO | S_IFREG, YPROC_ROOT); @@ -3398,9 +3547,28 @@ static int __init init_yaffs_fs(void) my_proc_entry->write_proc = yaffs_proc_write; my_proc_entry->read_proc = yaffs_proc_read; my_proc_entry->data = NULL; + return 0; } else { return -ENOMEM; - } + } +} + +#endif + + +static int __init init_yaffs_fs(void) +{ + int error = 0; + struct file_system_to_install *fsinst; + + yaffs_trace(YAFFS_TRACE_ALWAYS, + "yaffs built " __DATE__ " " __TIME__ " Installing."); + + mutex_init(&yaffs_context_lock); + + error = yaffs_procfs_init(); + if (error) + return error; /* Now add the file system entries */