#define YAFFS_COMPILE_EXPORTFS
#endif
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
+#define YAFFS_NEW_FOLLOW_LINK 1
+#else
+#define YAFFS_NEW_FOLLOW_LINK 0
+#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
#include <linux/config.h>
#include <linux/string.h>
#include <linux/ctype.h>
+#if (YAFFS_NEW_FOLLOW_LINK == 1)
+#include <linux/namei.h>
+#endif
+
#ifdef YAFFS_COMPILE_EXPORTFS
#include <linux/exportfs.h>
#endif
static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
int buflen);
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
+#if (YAFFS_NEW_FOLLOW_LINK == 1)
+void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias);
static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
#else
static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
#endif
+
static loff_t yaffs_dir_llseek(struct file *file, loff_t offset, int origin);
static struct address_space_operations yaffs_file_address_operations = {
static const struct inode_operations yaffs_symlink_inode_operations = {
.readlink = yaffs_readlink,
.follow_link = yaffs_follow_link,
+#if (YAFFS_NEW_FOLLOW_LINK == 1)
+ .put_link = yaffs_put_link,
+#endif
.setattr = yaffs_setattr,
#ifdef CONFIG_YAFFS_XATTR
.setxattr = yaffs_setxattr,
return ret;
}
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
+#if (YAFFS_NEW_FOLLOW_LINK == 1)
static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
#else
static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
yaffs_GrossLock(dev);
alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
-
yaffs_GrossUnlock(dev);
if (!alias) {
goto out;
}
- ret = vfs_follow_link(nd, alias);
- kfree(alias);
+#if (YAFFS_NEW_FOLLOW_LINK == 1)
+ nd_set_link(nd, alias);
+ ret = (int)alias;
out:
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
return ERR_PTR(ret);
#else
+ ret = vfs_follow_link(nd, alias);
+ kfree(alias);
+out:
return ret;
#endif
}
+#if (YAFFS_NEW_FOLLOW_LINK == 1)
+void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias) {
+ kfree(alias);
+}
+#endif
+
struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
yaffs_Object *obj);
int retval = 0;
struct yaffs_LinuxContext *context = yaffs_DeviceToLC(dev);
+ if(dev->readOnly)
+ return -1;
+
context->bgRunning = 1;
context->bgThread = kthread_run(yaffs_BackgroundThread,
struct yaffs_LinuxContext *context = NULL;
yaffs_DeviceParam *param;
+ int readOnly = 0;
+
yaffs_options options;
unsigned mount_id;
sb->s_op = &yaffs_super_ops;
sb->s_flags |= MS_NOATIME;
+ readOnly =((sb->s_flags & MS_RDONLY) != 0);
+
+
#ifdef YAFFS_COMPILE_EXPORTFS
sb->s_export_op = &yaffs_export_ops;
#endif
else if (!yaffs_devname(sb, devname_buf))
printk(KERN_INFO "yaffs: devname is NULL\n");
else
- printk(KERN_INFO "yaffs: dev is %d name is \"%s\"\n",
+ printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n",
sb->s_dev,
- yaffs_devname(sb, devname_buf));
+ yaffs_devname(sb, devname_buf),
+ readOnly ? "ro" : "rw");
if (!data_str)
data_str = "";
* Set the yaffs_Device up for mtd
*/
+ if (!readOnly && !(mtd->flags & MTD_WRITEABLE)){
+ readOnly = 1;
+ printk(KERN_INFO "yaffs: mtd is read only, setting superblock read only");
+ sb->s_flags |= MS_RDONLY;
+ }
+
dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
context = kmalloc(sizeof(struct yaffs_LinuxContext),GFP_KERNEL);
context->dev = dev;
context->superBlock = sb;
-
+ dev->readOnly = readOnly;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
sb->s_fs_info = dev;