udf: Factor out trimming of crtime
[sfrench/cifs-2.6.git] / fs / udf / inode.c
index 0f3db71753aa262f9281257263f845c857aba0e9..8cc5dbccebc742d910112e0df66eb8b2d4f5acb7 100644 (file)
@@ -57,14 +57,12 @@ static sector_t inode_getblk(struct inode *, sector_t, int *, int *);
 static int8_t udf_insert_aext(struct inode *, struct extent_position,
                              struct kernel_lb_addr, uint32_t);
 static void udf_split_extents(struct inode *, int *, int, int,
-                             struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
+                             struct kernel_long_ad *, int *);
 static void udf_prealloc_extents(struct inode *, int, int,
-                                struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
-static void udf_merge_extents(struct inode *,
-                             struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
-static void udf_update_extents(struct inode *,
-                              struct kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
-                              struct extent_position *);
+                                struct kernel_long_ad *, int *);
+static void udf_merge_extents(struct inode *, struct kernel_long_ad *, int *);
+static void udf_update_extents(struct inode *, struct kernel_long_ad *, int,
+                              int, struct extent_position *);
 static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
 static void __udf_clear_extent_cache(struct inode *inode)
@@ -747,11 +745,8 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
                                 ~(inode->i_sb->s_blocksize - 1));
                        udf_write_aext(inode, &cur_epos, &eloc, elen, 1);
                }
-               brelse(prev_epos.bh);
-               brelse(cur_epos.bh);
-               brelse(next_epos.bh);
                newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
-               return newblock;
+               goto out_free;
        }
 
        /* Are we beyond EOF? */
@@ -774,11 +769,9 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
                /* Create extents for the hole between EOF and offset */
                ret = udf_do_extend_file(inode, &prev_epos, laarr, offset);
                if (ret < 0) {
-                       brelse(prev_epos.bh);
-                       brelse(cur_epos.bh);
-                       brelse(next_epos.bh);
                        *err = ret;
-                       return 0;
+                       newblock = 0;
+                       goto out_free;
                }
                c = 0;
                offset = 0;
@@ -841,11 +834,9 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
                                iinfo->i_location.partitionReferenceNum,
                                goal, err);
                if (!newblocknum) {
-                       brelse(prev_epos.bh);
-                       brelse(cur_epos.bh);
-                       brelse(next_epos.bh);
                        *err = -ENOSPC;
-                       return 0;
+                       newblock = 0;
+                       goto out_free;
                }
                if (isBeyondEOF)
                        iinfo->i_lenExtents += inode->i_sb->s_blocksize;
@@ -857,14 +848,12 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
         * block */
        udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
 
-#ifdef UDF_PREALLOCATE
        /* We preallocate blocks only for regular files. It also makes sense
         * for directories but there's a problem when to drop the
         * preallocation. We might use some delayed work for that but I feel
         * it's overengineering for a filesystem like UDF. */
        if (S_ISREG(inode->i_mode))
                udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
-#endif
 
        /* merge any continuous blocks in laarr */
        udf_merge_extents(inode, laarr, &endnum);
@@ -874,15 +863,11 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
         * the new number of extents is less than the old number */
        udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
 
-       brelse(prev_epos.bh);
-       brelse(cur_epos.bh);
-       brelse(next_epos.bh);
-
        newblock = udf_get_pblock(inode->i_sb, newblocknum,
                                iinfo->i_location.partitionReferenceNum, 0);
        if (!newblock) {
                *err = -EIO;
-               return 0;
+               goto out_free;
        }
        *new = 1;
        iinfo->i_next_alloc_block = block;
@@ -893,13 +878,15 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
                udf_sync_inode(inode);
        else
                mark_inode_dirty(inode);
-
+out_free:
+       brelse(prev_epos.bh);
+       brelse(cur_epos.bh);
+       brelse(next_epos.bh);
        return newblock;
 }
 
 static void udf_split_extents(struct inode *inode, int *c, int offset,
-                             int newblocknum,
-                             struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+                             int newblocknum, struct kernel_long_ad *laarr,
                              int *endnum)
 {
        unsigned long blocksize = inode->i_sb->s_blocksize;
@@ -963,7 +950,7 @@ static void udf_split_extents(struct inode *inode, int *c, int offset,
 }
 
 static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
-                                struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+                                struct kernel_long_ad *laarr,
                                 int *endnum)
 {
        int start, length = 0, currlength = 0, i;
@@ -1058,8 +1045,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
        }
 }
 
-static void udf_merge_extents(struct inode *inode,
-                             struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+static void udf_merge_extents(struct inode *inode, struct kernel_long_ad *laarr,
                              int *endnum)
 {
        int i;
@@ -1158,8 +1144,7 @@ static void udf_merge_extents(struct inode *inode,
        }
 }
 
-static void udf_update_extents(struct inode *inode,
-                              struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
+static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr,
                               int startnum, int endnum,
                               struct extent_position *epos)
 {
@@ -1549,7 +1534,7 @@ reread:
                break;
        case ICBTAG_FILE_TYPE_SYMLINK:
                inode->i_data.a_ops = &udf_symlink_aops;
-               inode->i_op = &page_symlink_inode_operations;
+               inode->i_op = &udf_symlink_inode_operations;
                inode_nohighmem(inode);
                inode->i_mode = S_IFLNK | S_IRWXUGO;
                break;
@@ -1627,6 +1612,14 @@ static int udf_sync_inode(struct inode *inode)
        return udf_update_inode(inode, 1);
 }
 
+static void udf_adjust_time(struct udf_inode_info *iinfo, struct timespec time)
+{
+       if (iinfo->i_crtime.tv_sec > time.tv_sec ||
+           (iinfo->i_crtime.tv_sec == time.tv_sec &&
+            iinfo->i_crtime.tv_nsec > time.tv_nsec))
+               iinfo->i_crtime = time;
+}
+
 static int udf_update_inode(struct inode *inode, int do_sync)
 {
        struct buffer_head *bh = NULL;
@@ -1753,20 +1746,9 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                efe->objectSize = cpu_to_le64(inode->i_size);
                efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
 
-               if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec ||
-                   (iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec &&
-                    iinfo->i_crtime.tv_nsec > inode->i_atime.tv_nsec))
-                       iinfo->i_crtime = inode->i_atime;
-
-               if (iinfo->i_crtime.tv_sec > inode->i_mtime.tv_sec ||
-                   (iinfo->i_crtime.tv_sec == inode->i_mtime.tv_sec &&
-                    iinfo->i_crtime.tv_nsec > inode->i_mtime.tv_nsec))
-                       iinfo->i_crtime = inode->i_mtime;
-
-               if (iinfo->i_crtime.tv_sec > inode->i_ctime.tv_sec ||
-                   (iinfo->i_crtime.tv_sec == inode->i_ctime.tv_sec &&
-                    iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec))
-                       iinfo->i_crtime = inode->i_ctime;
+               udf_adjust_time(iinfo, inode->i_atime);
+               udf_adjust_time(iinfo, inode->i_mtime);
+               udf_adjust_time(iinfo, inode->i_ctime);
 
                udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime);
                udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime);
@@ -2286,8 +2268,7 @@ int8_t inode_bmap(struct inode *inode, sector_t block,
                  uint32_t *elen, sector_t *offset)
 {
        unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
-       loff_t lbcount = 0, bcount =
-           (loff_t) block << blocksize_bits;
+       loff_t lbcount = 0, bcount = (loff_t) block << blocksize_bits;
        int8_t etype;
        struct udf_inode_info *iinfo;