The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/jffs2/file.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * JFFS2 -- Journalling Flash File System, Version 2.
    3  *
    4  * Copyright (C) 2001 Red Hat, Inc.
    5  *
    6  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
    7  *
    8  * The original JFFS, from which the design for JFFS2 was derived,
    9  * was designed and implemented by Axis Communications AB.
   10  *
   11  * The contents of this file are subject to the Red Hat eCos Public
   12  * License Version 1.1 (the "Licence"); you may not use this file
   13  * except in compliance with the Licence.  You may obtain a copy of
   14  * the Licence at http://www.redhat.com/
   15  *
   16  * Software distributed under the Licence is distributed on an "AS IS"
   17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
   18  * See the Licence for the specific language governing rights and
   19  * limitations under the Licence.
   20  *
   21  * The Original Code is JFFS2 - Journalling Flash File System, version 2
   22  *
   23  * Alternatively, the contents of this file may be used under the
   24  * terms of the GNU General Public License version 2 (the "GPL"), in
   25  * which case the provisions of the GPL are applicable instead of the
   26  * above.  If you wish to allow the use of your version of this file
   27  * only under the terms of the GPL and not to allow others to use your
   28  * version of this file under the RHEPL, indicate your decision by
   29  * deleting the provisions above and replace them with the notice and
   30  * other provisions required by the GPL.  If you do not delete the
   31  * provisions above, a recipient may use your version of this file
   32  * under either the RHEPL or the GPL.
   33  *
   34  * $Id: file.c,v 1.58.2.6 2002/11/12 13:17:01 dwmw2 Exp $
   35  *
   36  */
   37 
   38 #include <linux/kernel.h>
   39 #include <linux/mtd/compatmac.h> /* for min() */
   40 #include <linux/slab.h>
   41 #include <linux/fs.h>
   42 #include <linux/pagemap.h>
   43 #include <linux/jffs2.h>
   44 #include "nodelist.h"
   45 #include <linux/crc32.h>
   46 
   47 extern int generic_file_open(struct inode *, struct file *) __attribute__((weak));
   48 extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) __attribute__((weak));
   49 
   50 
   51 int jffs2_null_fsync(struct file *filp, struct dentry *dentry, int datasync)
   52 {
   53         /* Move along. Nothing to see here */
   54         return 0;
   55 }
   56 
   57 struct file_operations jffs2_file_operations =
   58 {
   59         llseek:         generic_file_llseek,
   60         open:           generic_file_open,
   61         read:           generic_file_read,
   62         write:          generic_file_write,
   63         ioctl:          jffs2_ioctl,
   64         mmap:           generic_file_mmap,
   65         fsync:          jffs2_null_fsync
   66 };
   67 
   68 /* jffs2_file_inode_operations */
   69 
   70 struct inode_operations jffs2_file_inode_operations =
   71 {
   72         setattr:        jffs2_setattr
   73 };
   74 
   75 struct address_space_operations jffs2_file_address_operations =
   76 {
   77         readpage:       jffs2_readpage,
   78         prepare_write:  jffs2_prepare_write,
   79         commit_write:   jffs2_commit_write
   80 };
   81 
   82 int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
   83 {
   84         struct jffs2_full_dnode *old_metadata, *new_metadata;
   85         struct inode *inode = dentry->d_inode;
   86         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
   87         struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
   88         struct jffs2_raw_inode *ri;
   89         unsigned short dev;
   90         unsigned char *mdata = NULL;
   91         int mdatalen = 0;
   92         unsigned int ivalid;
   93         __u32 phys_ofs, alloclen;
   94         int ret;
   95         D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
   96         ret = inode_change_ok(inode, iattr);
   97         if (ret) 
   98                 return ret;
   99 
  100         /* Special cases - we don't want more than one data node
  101            for these types on the medium at any time. So setattr
  102            must read the original data associated with the node
  103            (i.e. the device numbers or the target name) and write
  104            it out again with the appropriate data attached */
  105         if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
  106                 /* For these, we don't actually need to read the old node */
  107                 dev =  (MAJOR(to_kdev_t(dentry->d_inode->i_rdev)) << 8) | 
  108                         MINOR(to_kdev_t(dentry->d_inode->i_rdev));
  109                 mdata = (char *)&dev;
  110                 mdatalen = sizeof(dev);
  111                 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
  112         } else if (S_ISLNK(inode->i_mode)) {
  113                 mdatalen = f->metadata->size;
  114                 mdata = kmalloc(f->metadata->size, GFP_USER);
  115                 if (!mdata)
  116                         return -ENOMEM;
  117                 ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen);
  118                 if (ret) {
  119                         kfree(mdata);
  120                         return ret;
  121                 }
  122                 D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
  123         }
  124 
  125         ri = jffs2_alloc_raw_inode();
  126         if (!ri) {
  127                 if (S_ISLNK(inode->i_mode))
  128                         kfree(mdata);
  129                 return -ENOMEM;
  130         }
  131                 
  132         ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
  133         if (ret) {
  134                 jffs2_free_raw_inode(ri);
  135                 if (S_ISLNK(inode->i_mode))
  136                          kfree(mdata);
  137                 return ret;
  138         }
  139         down(&f->sem);
  140         ivalid = iattr->ia_valid;
  141         
  142         ri->magic = JFFS2_MAGIC_BITMASK;
  143         ri->nodetype = JFFS2_NODETYPE_INODE;
  144         ri->totlen = sizeof(*ri) + mdatalen;
  145         ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
  146 
  147         ri->ino = inode->i_ino;
  148         ri->version = ++f->highest_version;
  149 
  150         ri->mode = (ivalid & ATTR_MODE)?iattr->ia_mode:inode->i_mode;
  151         ri->uid = (ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid;
  152         ri->gid = (ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid;
  153 
  154         if (ivalid & ATTR_MODE && ri->mode & S_ISGID &&
  155             !in_group_p(ri->gid) && !capable(CAP_FSETID))
  156                 ri->mode &= ~S_ISGID;
  157 
  158         ri->isize = (ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size;
  159         ri->atime = (ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime;
  160         ri->mtime = (ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime;
  161         ri->ctime = (ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime;
  162 
  163         ri->offset = 0;
  164         ri->csize = ri->dsize = mdatalen;
  165         ri->compr = JFFS2_COMPR_NONE;
  166         if (inode->i_size < ri->isize) {
  167                 /* It's an extension. Make it a hole node */
  168                 ri->compr = JFFS2_COMPR_ZERO;
  169                 ri->dsize = ri->isize - inode->i_size;
  170                 ri->offset = inode->i_size;
  171         }
  172         ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
  173         if (mdatalen)
  174                 ri->data_crc = crc32(0, mdata, mdatalen);
  175         else
  176                 ri->data_crc = 0;
  177 
  178         new_metadata = jffs2_write_dnode(inode, ri, mdata, mdatalen, phys_ofs, NULL);
  179         if (S_ISLNK(inode->i_mode))
  180                 kfree(mdata);
  181 
  182         jffs2_complete_reservation(c);
  183         
  184         if (IS_ERR(new_metadata)) {
  185                 jffs2_free_raw_inode(ri);
  186                 up(&f->sem);
  187                 return PTR_ERR(new_metadata);
  188         }
  189         /* It worked. Update the inode */
  190         inode->i_atime = ri->atime;
  191         inode->i_ctime = ri->ctime;
  192         inode->i_mtime = ri->mtime;
  193         inode->i_mode = ri->mode;
  194         inode->i_uid = ri->uid;
  195         inode->i_gid = ri->gid;
  196 
  197 
  198         old_metadata = f->metadata;
  199 
  200         if (inode->i_size > ri->isize) {
  201                 vmtruncate(inode, ri->isize);
  202                 jffs2_truncate_fraglist (c, &f->fraglist, ri->isize);
  203         }
  204 
  205         if (inode->i_size < ri->isize) {
  206                 jffs2_add_full_dnode_to_inode(c, f, new_metadata);
  207                 inode->i_size = ri->isize;
  208                 f->metadata = NULL;
  209         } else {
  210                 f->metadata = new_metadata;
  211         }
  212         if (old_metadata) {
  213                 jffs2_mark_node_obsolete(c, old_metadata->raw);
  214                 jffs2_free_full_dnode(old_metadata);
  215         }
  216         jffs2_free_raw_inode(ri);
  217         up(&f->sem);
  218         return 0;
  219 }
  220 
  221 int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
  222 {
  223         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  224         struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
  225         struct jffs2_node_frag *frag = f->fraglist;
  226         __u32 offset = pg->index << PAGE_CACHE_SHIFT;
  227         __u32 end = offset + PAGE_CACHE_SIZE;
  228         unsigned char *pg_buf;
  229         int ret;
  230 
  231         D1(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%x\n", inode->i_ino, offset));
  232 
  233         if (!PageLocked(pg))
  234                 PAGE_BUG(pg);
  235 
  236         while(frag && frag->ofs + frag->size  <= offset) {
  237                 //              D1(printk(KERN_DEBUG "skipping frag %d-%d; before the region we care about\n", frag->ofs, frag->ofs + frag->size));
  238                 frag = frag->next;
  239         }
  240 
  241         pg_buf = kmap(pg);
  242 
  243         /* XXX FIXME: Where a single physical node actually shows up in two
  244            frags, we read it twice. Don't do that. */
  245         /* Now we're pointing at the first frag which overlaps our page */
  246         while(offset < end) {
  247                 D2(printk(KERN_DEBUG "jffs2_readpage: offset %d, end %d\n", offset, end));
  248                 if (!frag || frag->ofs > offset) {
  249                         __u32 holesize = end - offset;
  250                         if (frag) {
  251                                 D1(printk(KERN_NOTICE "Eep. Hole in ino %ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", inode->i_ino, frag->ofs, offset));
  252                                 holesize = min(holesize, frag->ofs - offset);
  253                                 D1(jffs2_print_frag_list(f));
  254                         }
  255                         D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
  256                         memset(pg_buf, 0, holesize);
  257                         pg_buf += holesize;
  258                         offset += holesize;
  259                         continue;
  260                 } else if (frag->ofs < offset && (offset & (PAGE_CACHE_SIZE-1)) != 0) {
  261                         D1(printk(KERN_NOTICE "Eep. Overlap in ino #%ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n",
  262                                   inode->i_ino, frag->ofs, offset));
  263                         D1(jffs2_print_frag_list(f));
  264                         memset(pg_buf, 0, end - offset);
  265                         ClearPageUptodate(pg);
  266                         SetPageError(pg);
  267                         kunmap(pg);
  268                         return -EIO;
  269                 } else if (!frag->node) {
  270                         __u32 holeend = min(end, frag->ofs + frag->size);
  271                         D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size));
  272                         memset(pg_buf, 0, holeend - offset);
  273                         pg_buf += holeend - offset;
  274                         offset = holeend;
  275                         frag = frag->next;
  276                         continue;
  277                 } else {
  278                         __u32 readlen;
  279                         __u32 fragofs; /* offset within the frag to start reading */
  280 
  281                         fragofs = offset - frag->ofs;
  282                         readlen = min(frag->size - fragofs, end - offset);
  283                         D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs+fragofs, 
  284                                   fragofs+frag->ofs+readlen, frag->node->raw->flash_offset & ~3));
  285                         ret = jffs2_read_dnode(c, frag->node, pg_buf, fragofs + frag->ofs - frag->node->ofs, readlen);
  286                         D2(printk(KERN_DEBUG "node read done\n"));
  287                         if (ret) {
  288                                 D1(printk(KERN_DEBUG"jffs2_readpage error %d\n",ret));
  289                                 memset(pg_buf, 0, readlen);
  290                                 ClearPageUptodate(pg);
  291                                 SetPageError(pg);
  292                                 kunmap(pg);
  293                                 return ret;
  294                         }
  295                 
  296                         pg_buf += readlen;
  297                         offset += readlen;
  298                         frag = frag->next;
  299                         D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
  300                 }
  301         }
  302         D2(printk(KERN_DEBUG "readpage finishing\n"));
  303         SetPageUptodate(pg);
  304         ClearPageError(pg);
  305 
  306         flush_dcache_page(pg);
  307 
  308         kunmap(pg);
  309         D1(printk(KERN_DEBUG "readpage finished\n"));
  310         return 0;
  311 }
  312 
  313 int jffs2_do_readpage_unlock(struct inode *inode, struct page *pg)
  314 {
  315         int ret = jffs2_do_readpage_nolock(inode, pg);
  316         UnlockPage(pg);
  317         return ret;
  318 }
  319 
  320 
  321 int jffs2_readpage (struct file *filp, struct page *pg)
  322 {
  323         struct jffs2_inode_info *f = JFFS2_INODE_INFO(pg->mapping->host);
  324         int ret;
  325         
  326         down(&f->sem);
  327         ret = jffs2_do_readpage_unlock(pg->mapping->host, pg);
  328         up(&f->sem);
  329         return ret;
  330 }
  331 
  332 int jffs2_prepare_write (struct file *filp, struct page *pg, unsigned start, unsigned end)
  333 {
  334         struct inode *inode = pg->mapping->host;
  335         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  336         __u32 pageofs = pg->index << PAGE_CACHE_SHIFT;
  337         int ret = 0;
  338 
  339         D1(printk(KERN_DEBUG "jffs2_prepare_write() nrpages %ld\n", inode->i_mapping->nrpages));
  340 
  341         if (pageofs > inode->i_size) {
  342                 /* Make new hole frag from old EOF to new page */
  343                 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
  344                 struct jffs2_raw_inode ri;
  345                 struct jffs2_full_dnode *fn;
  346                 __u32 phys_ofs, alloc_len;
  347                 
  348                 D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
  349                           (unsigned int)inode->i_size, pageofs));
  350 
  351                 ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);
  352                 if (ret)
  353                         return ret;
  354 
  355                 down(&f->sem);
  356                 memset(&ri, 0, sizeof(ri));
  357 
  358                 ri.magic = JFFS2_MAGIC_BITMASK;
  359                 ri.nodetype = JFFS2_NODETYPE_INODE;
  360                 ri.totlen = sizeof(ri);
  361                 ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
  362 
  363                 ri.ino = f->inocache->ino;
  364                 ri.version = ++f->highest_version;
  365                 ri.mode = inode->i_mode;
  366                 ri.uid = inode->i_uid;
  367                 ri.gid = inode->i_gid;
  368                 ri.isize = max((__u32)inode->i_size, pageofs);
  369                 ri.atime = ri.ctime = ri.mtime = CURRENT_TIME;
  370                 ri.offset = inode->i_size;
  371                 ri.dsize = pageofs - inode->i_size;
  372                 ri.csize = 0;
  373                 ri.compr = JFFS2_COMPR_ZERO;
  374                 ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
  375                 ri.data_crc = 0;
  376                 
  377                 fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL);
  378                 jffs2_complete_reservation(c);
  379                 if (IS_ERR(fn)) {
  380                         ret = PTR_ERR(fn);
  381                         up(&f->sem);
  382                         return ret;
  383                 }
  384                 ret = jffs2_add_full_dnode_to_inode(c, f, fn);
  385                 if (f->metadata) {
  386                         jffs2_mark_node_obsolete(c, f->metadata->raw);
  387                         jffs2_free_full_dnode(f->metadata);
  388                         f->metadata = NULL;
  389                 }
  390                 if (ret) {
  391                         D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret));
  392                         jffs2_mark_node_obsolete(c, fn->raw);
  393                         jffs2_free_full_dnode(fn);
  394                         up(&f->sem);
  395                         return ret;
  396                 }
  397                 inode->i_size = pageofs;
  398                 up(&f->sem);
  399         }
  400         
  401 
  402         /* Read in the page if it wasn't already present, unless it's a whole page */
  403         if (!Page_Uptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
  404                 down(&f->sem);
  405                 ret = jffs2_do_readpage_nolock(inode, pg);
  406                 up(&f->sem);
  407         }
  408         D1(printk(KERN_DEBUG "end prepare_write(). pg->flags %lx\n", pg->flags));
  409         return ret;
  410 }
  411 
  412 int jffs2_commit_write (struct file *filp, struct page *pg, unsigned start, unsigned end)
  413 {
  414         /* Actually commit the write from the page cache page we're looking at.
  415          * For now, we write the full page out each time. It sucks, but it's simple
  416          */
  417         struct inode *inode = pg->mapping->host;
  418         struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  419         struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
  420         __u32 newsize = max_t(__u32, filp->f_dentry->d_inode->i_size, (pg->index << PAGE_CACHE_SHIFT) + end);
  421         __u32 file_ofs = (pg->index << PAGE_CACHE_SHIFT);
  422         __u32 writelen = min((__u32)PAGE_CACHE_SIZE, newsize - file_ofs);
  423         struct jffs2_raw_inode *ri;
  424         int ret = 0;
  425         ssize_t writtenlen = 0;
  426 
  427         D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
  428 
  429         if (!start && end == PAGE_CACHE_SIZE) {
  430                 /* We need to avoid deadlock with page_cache_read() in
  431                    jffs2_garbage_collect_pass(). So we have to mark the
  432                    page up to date, to prevent page_cache_read() from 
  433                    trying to re-lock it. */
  434                 SetPageUptodate(pg);
  435         }
  436 
  437         ri = jffs2_alloc_raw_inode();
  438         if (!ri)
  439                 return -ENOMEM;
  440 
  441         while(writelen) {
  442                 struct jffs2_full_dnode *fn;
  443                 unsigned char *comprbuf = NULL;
  444                 unsigned char comprtype = JFFS2_COMPR_NONE;
  445                 __u32 phys_ofs, alloclen;
  446                 __u32 datalen, cdatalen;
  447 
  448                 D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, file_ofs));
  449 
  450                 ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);
  451                 if (ret) {
  452                         SetPageError(pg);
  453                         D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
  454                         break;
  455                 }
  456                 down(&f->sem);
  457                 datalen = writelen;
  458                 cdatalen = min(alloclen - sizeof(*ri), writelen);
  459 
  460                 comprbuf = kmalloc(cdatalen, GFP_KERNEL);
  461                 if (comprbuf) {
  462                         comprtype = jffs2_compress(page_address(pg)+ (file_ofs & (PAGE_CACHE_SIZE-1)), comprbuf, &datalen, &cdatalen);
  463                 }
  464                 if (comprtype == JFFS2_COMPR_NONE) {
  465                         /* Either compression failed, or the allocation of comprbuf failed */
  466                         if (comprbuf)
  467                                 kfree(comprbuf);
  468                         comprbuf = page_address(pg) + (file_ofs & (PAGE_CACHE_SIZE -1));
  469                         datalen = cdatalen;
  470                 }
  471                 /* Now comprbuf points to the data to be written, be it compressed or not.
  472                    comprtype holds the compression type, and comprtype == JFFS2_COMPR_NONE means
  473                    that the comprbuf doesn't need to be kfree()d. 
  474                 */
  475 
  476                 ri->magic = JFFS2_MAGIC_BITMASK;
  477                 ri->nodetype = JFFS2_NODETYPE_INODE;
  478                 ri->totlen = sizeof(*ri) + cdatalen;
  479                 ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
  480 
  481                 ri->ino = inode->i_ino;
  482                 ri->version = ++f->highest_version;
  483                 ri->mode = inode->i_mode;
  484                 ri->uid = inode->i_uid;
  485                 ri->gid = inode->i_gid;
  486                 ri->isize = max((__u32)inode->i_size, file_ofs + datalen);
  487                 ri->atime = ri->ctime = ri->mtime = CURRENT_TIME;
  488                 ri->offset = file_ofs;
  489                 ri->csize = cdatalen;
  490                 ri->dsize = datalen;
  491                 ri->compr = comprtype;
  492                 ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
  493                 ri->data_crc = crc32(0, comprbuf, cdatalen);
  494 
  495                 fn = jffs2_write_dnode(inode, ri, comprbuf, cdatalen, phys_ofs, NULL);
  496 
  497                 jffs2_complete_reservation(c);
  498 
  499                 if (comprtype != JFFS2_COMPR_NONE)
  500                         kfree(comprbuf);
  501 
  502                 if (IS_ERR(fn)) {
  503                         ret = PTR_ERR(fn);
  504                         up(&f->sem);
  505                         SetPageError(pg);
  506                         break;
  507                 }
  508                 ret = jffs2_add_full_dnode_to_inode(c, f, fn);
  509                 if (f->metadata) {
  510                         jffs2_mark_node_obsolete(c, f->metadata->raw);
  511                         jffs2_free_full_dnode(f->metadata);
  512                         f->metadata = NULL;
  513                 }
  514                 up(&f->sem);
  515                 if (ret) {
  516                         /* Eep */
  517                         D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret));
  518                         jffs2_mark_node_obsolete(c, fn->raw);
  519                         jffs2_free_full_dnode(fn);
  520                         SetPageError(pg);
  521                         break;
  522                 }
  523                 inode->i_size = ri->isize;
  524                 inode->i_blocks = (inode->i_size + 511) >> 9;
  525                 inode->i_ctime = inode->i_mtime = ri->ctime;
  526                 if (!datalen) {
  527                         printk(KERN_WARNING "Eep. We didn't actually write any bloody data\n");
  528                         ret = -EIO;
  529                         SetPageError(pg);
  530                         break;
  531                 }
  532                 D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen));
  533                 writtenlen += datalen;
  534                 file_ofs += datalen;
  535                 writelen -= datalen;
  536         }
  537 
  538         jffs2_free_raw_inode(ri);
  539 
  540         if (writtenlen < end) {
  541                 /* generic_file_write has written more to the page cache than we've
  542                    actually written to the medium. Mark the page !Uptodate so that 
  543                    it gets reread */
  544                 D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n"));
  545                 SetPageError(pg);
  546                 ClearPageUptodate(pg);
  547         }
  548         if (writtenlen <= start) {
  549                 /* We didn't even get to the start of the affected part */
  550                 ret = ret?ret:-ENOSPC;
  551                 D1(printk(KERN_DEBUG "jffs2_commit_write(): Only %x bytes written to page. start (%x) not reached, returning %d\n", writtenlen, start, ret));
  552         }
  553         writtenlen = min(end-start, writtenlen-start);
  554 
  555         D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d. nrpages is %ld\n",writtenlen?writtenlen:ret, inode->i_mapping->nrpages));
  556         return writtenlen?writtenlen:ret;
  557 }

Cache object: e146ca09a759afd55a3a4e79564e52df


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.