#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 void yaffs_MarkSuperBlockDirty(yaffs_Device *dev);
+
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);
static int yaffs_writepage(struct page *page)
#endif
{
+ yaffs_Device *dev;
struct address_space *mapping = page->mapping;
struct inode *inode;
unsigned long end_index;
buffer = kmap(page);
obj = yaffs_InodeToObject(inode);
- yaffs_GrossLock(obj->myDev);
+ dev = obj->myDev;
+ yaffs_GrossLock(dev);
T(YAFFS_TRACE_OS,
(TSTR("yaffs_writepage at %08x, size %08x\n"),
nWritten = yaffs_WriteDataToFile(obj, buffer,
page->index << PAGE_CACHE_SHIFT, nBytes, 0);
+ yaffs_MarkSuperBlockDirty(dev);
+
T(YAFFS_TRACE_OS,
(TSTR("writepag1: obj = %05x, ino = %05x\n"),
(int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
- yaffs_GrossUnlock(obj->myDev);
+ yaffs_GrossUnlock(dev);
kunmap(page);
set_page_writeback(page);
nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0);
+ yaffs_MarkSuperBlockDirty(dev);
+
T(YAFFS_TRACE_OS,
(TSTR("yaffs_file_write: %d(%x) bytes written\n"),
(unsigned )n,(unsigned)n));
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;