WIP large file support
authorCharles Manning <cdhmanning@gmail.com>
Tue, 20 Dec 2011 02:58:11 +0000 (15:58 +1300)
committerCharles Manning <cdhmanning@gmail.com>
Tue, 20 Dec 2011 02:58:11 +0000 (15:58 +1300)
Signed-off-by: Charles Manning <cdhmanning@gmail.com>
linux-tests/Makefile [new file with mode: 0644]
linux-tests/writebigsparse.c [new file with mode: 0644]
linux-tests/xattrtest.c
yaffs_guts.c
yaffs_guts.h
yaffs_verify.c
yaffs_vfs_multi.c

diff --git a/linux-tests/Makefile b/linux-tests/Makefile
new file mode 100644 (file)
index 0000000..1f1d56e
--- /dev/null
@@ -0,0 +1,15 @@
+CFLAGS += -Wall -D_FILE_OFFSET_BITS=64
+
+TARGETS = xattrtest writebigsparse
+all: $(TARGETS)
+
+xattrtest: xattrtest.c
+       gcc $(CFLAGS) -o $@ $<
+
+writebigsparse: writebigsparse.c
+       gcc $(CFLAGS) -o $@ $<
+       
+
+.PHONEY: clean
+clean:
+       rm -f $(TARGETS)
diff --git a/linux-tests/writebigsparse.c b/linux-tests/writebigsparse.c
new file mode 100644 (file)
index 0000000..0d70128
--- /dev/null
@@ -0,0 +1,80 @@
+#define _LARGEFILE64_SOURCE
+#include<stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+int handle;
+
+#define N_WRITES 8000
+#define STRIDE  1000
+
+#define BUFFER_N 2000
+unsigned  buffer[BUFFER_N];
+
+
+void set_buffer(int n)
+{
+       int i;
+       for(i = 0; i < BUFFER_N; i++)
+               buffer[i] = i + n;
+}
+
+void write_big_sparse_file(int h)
+{
+       int i;
+       off64_t offset = 0;
+       off64_t pos;
+       int n = sizeof(buffer);
+       int wrote;
+       
+       for(i = 0; i < 4000; i++) {
+               set_buffer(i);
+               pos = lseek64(h, offset, SEEK_SET);
+               if(pos != offset) {
+                       printf("mismatched seek pos %lld offset %lld\n",
+                               pos, offset);
+                       exit(1);
+               }
+               wrote = write(h, buffer, n);
+               
+               if(wrote != n) {
+                       printf("mismatched write wrote %d n %d\n", wrote, n);
+                       exit(1);
+               }
+               
+               offset += (STRIDE * sizeof(buffer));
+       }
+}
+
+
+
+
+void verify_big_sparse_file(int h)
+{
+}
+
+int main(int argc, char *argv[])
+{
+
+       if(argc < 2) {
+               printf("Gimme a file name!\n");
+               exit(1);
+       }
+       
+       handle = open(argv[1], O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
+       
+       if(handle < 0) {
+               perror("opening file");
+               exit(1);
+       }
+       
+       write_big_sparse_file(handle);
+       system("sudo echo 3 > /proc/sys/vm/drop_caches");
+       verify_big_sparse_file(handle);
+       
+       printf("Job done\n");
+       return 0;
+}
index 4e92dfc09f0f71e2fc36b124981a5dd8a760c584..3a6931b962db3a7588add1e59bf06d6ce634d25d 100644 (file)
@@ -19,7 +19,8 @@
 #include <string.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-
+#include <unistd.h>
+#include <sys/xattr.h>
 
 static void print_xattrib_val(const char *path, const char *name)
 {
@@ -66,8 +67,6 @@ void basic_xattr_test(const char *mountpt)
        int h;
        int result;
        int val1;
-       int valread;
-
        
        strcpy(name,mountpt);
        strcat(name,"/");
@@ -115,4 +114,5 @@ int simulate_power_failure;
 int main(int argc, char *argv[])
 {
        basic_xattr_test("/mnt/");      
+       return 0;
 }
index 146fb2b75ca5a7f3ae78cedd6cfda356da4d61dd..79a798808c56660f8bbe223d90b2a2e9e1488d1e 100644 (file)
@@ -44,8 +44,8 @@ static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
 
 /* Function to calculate chunk and offset */
 
-static inline void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
-                                       int *chunk_out, u32 *offset_out)
+void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
+                               int *chunk_out, u32 *offset_out)
 {
        int chunk;
        u32 offset;
@@ -5001,7 +5001,13 @@ void yaffs_oh_size_load(struct yaffs_obj_hdr *oh, loff_t fsize)
 
 loff_t yaffs_oh_to_size(struct yaffs_obj_hdr *oh)
 {
-       loff_t retval = (((loff_t) oh->file_size_high) << 32) |
+       loff_t retval;
+       
+       if(~(oh->file_size_high))
+               retval = (((loff_t) oh->file_size_high) << 32) |
                        (((loff_t) oh->file_size_low) & 0xFFFFFFFF);
+       else
+               retval = (loff_t) oh->file_size_low;
+
        return retval;
 }
index 93809665c6097c0524eba88ea428018b9984f6a3..a063776913780d65dfa9ff20e45df468e9c0f726 100644 (file)
@@ -949,7 +949,9 @@ u32 yaffs_get_group_base(struct yaffs_dev *dev, struct yaffs_tnode *tn,
 
 int yaffs_is_non_empty_dir(struct yaffs_obj *obj);
 
-/*\
+void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
+                               int *chunk_out, u32 *offset_out);
+/*
  * Marshalling functions to get loff_t file sizes into aand out of
  * object headers.
  */
index b3e540dd52a3656c223587431bda39b76b56e502..db48e56de96f2dd7f46f1052248b9af65f132f0f 100644 (file)
@@ -222,11 +222,13 @@ void yaffs_verify_oh(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh,
 
 void yaffs_verify_file(struct yaffs_obj *obj)
 {
+       u32 x;
        int required_depth;
        int actual_depth;
-       u32 last_chunk;
+       int last_chunk;
+       u32 offset_in_chunk;
        u32 the_chunk;
-       u32 x;
+
        u32 i;
        struct yaffs_dev *dev;
        struct yaffs_ext_tags tags;
@@ -242,9 +244,11 @@ void yaffs_verify_file(struct yaffs_obj *obj)
        dev = obj->my_dev;
        obj_id = obj->obj_id;
 
+
        /* Check file size is consistent with tnode depth */
-       last_chunk =
-           obj->variant.file_variant.file_size / dev->data_bytes_per_chunk + 1;
+       yaffs_addr_to_chunk(dev, obj->variant.file_variant.file_size,
+                               &last_chunk, &offset_in_chunk);
+       last_chunk++;
        x = last_chunk >> YAFFS_TNODES_LEVEL0_BITS;
        required_depth = 0;
        while (x > 0) {
index b8e51243051a27fc7a17c3b79dbbfd72555699b1..8773b761dc97c50a8bee4c4a9f174240fc628e4c 100644 (file)
@@ -1068,9 +1068,9 @@ static int yaffs_writepage(struct page *page)
 
                if (page->index > end_index || !n_bytes) {
                        yaffs_trace(YAFFS_TRACE_OS,
-                               "yaffs_writepage at %08x, inode size = %08x!!",
-                               (unsigned)(page->index << PAGE_CACHE_SHIFT),
-                               (unsigned)inode->i_size);
+                               "yaffs_writepage at %lld, inode size = %lld!!",
+                               ((loff_t)page->index) << PAGE_CACHE_SHIFT,
+                               inode->i_size);
                        yaffs_trace(YAFFS_TRACE_OS,
                                "                -> don't care!!");
 
@@ -1094,11 +1094,11 @@ static int yaffs_writepage(struct page *page)
        yaffs_gross_lock(dev);
 
        yaffs_trace(YAFFS_TRACE_OS,
-               "yaffs_writepage at %08x, size %08x",
-               (unsigned)(page->index << PAGE_CACHE_SHIFT), n_bytes);
+               "yaffs_writepage at %lld, size %08x",
+               ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes);
        yaffs_trace(YAFFS_TRACE_OS,
-               "writepag0: obj = %05x, ino = %05x",
-               (int)obj->variant.file_variant.file_size, (int)inode->i_size);
+               "writepag0: obj = %lld, ino = %lld",
+               obj->variant.file_variant.file_size, inode->i_size);
 
        n_written = yaffs_wr_file(obj, buffer,
                                  page->index << PAGE_CACHE_SHIFT, n_bytes, 0);
@@ -1106,8 +1106,8 @@ static int yaffs_writepage(struct page *page)
        yaffs_touch_super(dev);
 
        yaffs_trace(YAFFS_TRACE_OS,
-               "writepag1: obj = %05x, ino = %05x",
-               (int)obj->variant.file_variant.file_size, (int)inode->i_size);
+               "writepag1: obj = %lld, ino = %lld",
+               obj->variant.file_variant.file_size, inode->i_size);
 
        yaffs_gross_unlock(dev);
 
@@ -1206,8 +1206,8 @@ static int yaffs_write_end(struct file *filp, struct address_space *mapping,
        addr = kva + offset_into_page;
 
        yaffs_trace(YAFFS_TRACE_OS,
-               "yaffs_write_end addr %p pos %x n_bytes %d",
-               addr, (unsigned)pos, copied);
+               "yaffs_write_end addr %p pos %lld n_bytes %d",
+               addr, pos, copied);
 
        ret = yaffs_file_write(filp, addr, copied, &pos);
 
@@ -1236,17 +1236,12 @@ static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
        int n_bytes = to - offset;
        int n_written;
 
-       unsigned spos = pos;
-       unsigned saddr;
-
        kva = kmap(pg);
        addr = kva + offset;
 
-       saddr = (unsigned)addr;
-
        yaffs_trace(YAFFS_TRACE_OS,
-               "yaffs_commit_write addr %x pos %x n_bytes %d",
-               saddr, spos, n_bytes);
+               "yaffs_commit_write addr %p pos %lld n_bytes %d",
+               addr, pos, n_bytes);
 
        n_written = yaffs_file_write(f, addr, n_bytes, &pos);
 
@@ -1333,9 +1328,9 @@ static void yaffs_fill_inode_from_obj(struct inode *inode,
                inode->i_nlink = yaffs_get_obj_link_count(obj);
 
                yaffs_trace(YAFFS_TRACE_OS,
-                       "yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
+                       "yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
                        inode->i_mode, inode->i_uid, inode->i_gid,
-                       (int)inode->i_size, atomic_read(&inode->i_count));
+                       inode->i_size, atomic_read(&inode->i_count));
 
                switch (obj->yst_mode & S_IFMT) {
                default:        /* fifo, device or socket */
@@ -1410,7 +1405,8 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
                                loff_t * pos)
 {
        struct yaffs_obj *obj;
-       int n_written, ipos;
+       int n_written;
+       loff_t ipos;
        struct inode *inode;
        struct yaffs_dev *dev;
 
@@ -1434,8 +1430,8 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
                ipos = *pos;
 
        yaffs_trace(YAFFS_TRACE_OS,
-               "yaffs_file_write about to write writing %u(%x) bytes to object %d at %d(%x)",
-               (unsigned)n, (unsigned)n, obj->obj_id, ipos, ipos);
+               "yaffs_file_write about to write writing %u(%x) bytes to object %d at %lld",
+               (unsigned)n, (unsigned)n, obj->obj_id, ipos);
 
        n_written = yaffs_wr_file(obj, buf, ipos, n, 0);
 
@@ -1453,7 +1449,7 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
                        inode->i_blocks = (ipos + 511) >> 9;
 
                        yaffs_trace(YAFFS_TRACE_OS,
-                               "yaffs_file_write size updated to %d bytes, %d blocks",
+                               "yaffs_file_write size updated to %lld bytes, %d blocks",
                                ipos, (int)(inode->i_blocks));
                }
 
@@ -1920,10 +1916,11 @@ static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
        yaffs_trace(YAFFS_TRACE_OS,
                "yaffs_setattr of object %d",
                yaffs_inode_to_obj(inode)->obj_id);
-
+#if 0
        /* Fail if a requested resize >= 2GB */
        if (attr->ia_valid & ATTR_SIZE && (attr->ia_size >> 31))
                error = -EINVAL;
+#endif
 
        if (error == 0)
                error = inode_change_ok(inode, attr);