Common subdirectories: linux-2.6.18-238.12.1/fs/9p and linux-2.6.18-274.3.1/fs/9p Common subdirectories: linux-2.6.18-238.12.1/fs/adfs and linux-2.6.18-274.3.1/fs/adfs Common subdirectories: linux-2.6.18-238.12.1/fs/affs and linux-2.6.18-274.3.1/fs/affs Common subdirectories: linux-2.6.18-238.12.1/fs/afs and linux-2.6.18-274.3.1/fs/afs Common subdirectories: linux-2.6.18-238.12.1/fs/autofs and linux-2.6.18-274.3.1/fs/autofs Common subdirectories: linux-2.6.18-238.12.1/fs/autofs4 and linux-2.6.18-274.3.1/fs/autofs4 Common subdirectories: linux-2.6.18-238.12.1/fs/befs and linux-2.6.18-274.3.1/fs/befs Common subdirectories: linux-2.6.18-238.12.1/fs/bfs and linux-2.6.18-274.3.1/fs/bfs diff -up linux-2.6.18-238.12.1/fs/bio.c linux-2.6.18-274.3.1/fs/bio.c --- linux-2.6.18-238.12.1/fs/bio.c 2011-06-09 18:00:06.733084779 +0800 +++ linux-2.6.18-274.3.1/fs/bio.c 2011-10-21 01:40:04.281940867 +0800 @@ -238,12 +238,12 @@ inline int bio_phys_segments(request_que return bio->bi_phys_segments; } +/* + * This function is DEPRECATED. Use bio_phys_segments instead. + */ inline int bio_hw_segments(request_queue_t *q, struct bio *bio) { - if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) - blk_recount_segments(q, bio); - - return bio->bi_hw_segments; + return bio_phys_segments(q, bio); } /** @@ -361,8 +361,7 @@ static int __bio_add_page(request_queue_ */ while (bio->bi_phys_segments >= q->max_phys_segments - || bio->bi_hw_segments >= q->max_hw_segments - || BIOVEC_VIRT_OVERSIZE(bio->bi_size)) { + || bio->bi_phys_segments >= q->max_hw_segments) { if (retried_segments) return 0; @@ -399,13 +398,11 @@ static int __bio_add_page(request_queue_ } /* If we may be able to merge these biovecs, force a recount */ - if (bio->bi_vcnt && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec) || - BIOVEC_VIRT_MERGEABLE(bvec-1, bvec))) + if (bio->bi_vcnt && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec))) bio->bi_flags &= ~(1 << BIO_SEG_VALID); bio->bi_vcnt++; bio->bi_phys_segments++; - bio->bi_hw_segments++; done: bio->bi_size += len; return len; diff -up linux-2.6.18-238.12.1/fs/block_dev.c linux-2.6.18-274.3.1/fs/block_dev.c --- linux-2.6.18-238.12.1/fs/block_dev.c 2011-07-05 14:54:27.073615771 +0800 +++ linux-2.6.18-274.3.1/fs/block_dev.c 2011-10-21 01:40:04.320941044 +0800 @@ -372,6 +372,7 @@ struct block_device *bdget(dev_t dev) if (inode->i_state & I_NEW) { bdev->bd_contains = NULL; + bdev->bd_super = NULL; bdev->bd_inode = inode; bdev->bd_block_size = (1 << inode->i_blkbits); bdev->bd_part_count = 0; @@ -877,7 +878,6 @@ void check_disk_size_change(struct gendi "%s: detected capacity change from %lld to %lld\n", name, bdev_size, disk_size); i_size_write(bdev->bd_inode, disk_size); - flush_disk(bdev); } } EXPORT_SYMBOL(check_disk_size_change); Common subdirectories: linux-2.6.18-238.12.1/fs/cachefiles and linux-2.6.18-274.3.1/fs/cachefiles Common subdirectories: linux-2.6.18-238.12.1/fs/cifs and linux-2.6.18-274.3.1/fs/cifs Common subdirectories: linux-2.6.18-238.12.1/fs/coda and linux-2.6.18-274.3.1/fs/coda diff -up linux-2.6.18-238.12.1/fs/compat.c linux-2.6.18-274.3.1/fs/compat.c --- linux-2.6.18-238.12.1/fs/compat.c 2011-06-09 18:00:18.487084785 +0800 +++ linux-2.6.18-274.3.1/fs/compat.c 2011-10-21 01:40:04.744942932 +0800 @@ -1790,7 +1790,7 @@ asmlinkage long compat_sys_select(int n, timeout = -1; /* infinite */ else { timeout = ROUND_UP(tv.tv_usec, 1000000/HZ); - timeout += tv.tv_sec * HZ; + timeout += (s64)tv.tv_sec * HZ; } } @@ -1858,7 +1858,7 @@ asmlinkage long compat_sys_pselect7(int if (tsp) { if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) { timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ); - timeout += ts.tv_sec * (unsigned long)HZ; + timeout += (s64)ts.tv_sec * (unsigned long)HZ; ts.tv_sec = 0; ts.tv_nsec = 0; } else { @@ -1939,7 +1939,7 @@ asmlinkage long compat_sys_ppoll(struct the number of seconds that can be expressed in an s64. Otherwise the compiler bitches at us */ timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ); - timeout += ts.tv_sec * HZ; + timeout += (s64)ts.tv_sec * HZ; } if (sigmask) { Common subdirectories: linux-2.6.18-238.12.1/fs/configfs and linux-2.6.18-274.3.1/fs/configfs Common subdirectories: linux-2.6.18-238.12.1/fs/cramfs and linux-2.6.18-274.3.1/fs/cramfs diff -up linux-2.6.18-238.12.1/fs/dcache.c linux-2.6.18-274.3.1/fs/dcache.c --- linux-2.6.18-238.12.1/fs/dcache.c 2011-07-05 14:54:27.514615770 +0800 +++ linux-2.6.18-274.3.1/fs/dcache.c 2011-10-21 01:40:04.843943375 +0800 @@ -1057,6 +1057,28 @@ static inline struct hlist_head *d_hash( return dentry_hashtable + (hash & D_HASHMASK); } +static struct dentry * __d_find_any_alias(struct inode *inode) +{ + struct dentry *alias; + + if (list_empty(&inode->i_dentry)) + return NULL; + alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); + __dget_locked(alias); + return alias; +} + +static struct dentry * d_find_any_alias(struct inode *inode) +{ + struct dentry *de; + + spin_lock(&dcache_lock); + de = __d_find_any_alias(inode); + spin_unlock(&dcache_lock); + return de; +} + + /** * d_alloc_anon - allocate an anonymous dentry * @inode: inode to allocate the dentry for @@ -1141,19 +1163,50 @@ struct dentry * d_alloc_anon(struct inod */ struct dentry *d_obtain_alias(struct inode *inode) { - struct dentry *dentry; + static const struct qstr anonstring = { .name = "" }; + struct dentry *tmp; + struct dentry *res; if (!inode) return ERR_PTR(-ESTALE); if (IS_ERR(inode)) return ERR_CAST(inode); - dentry = d_alloc_anon(inode); - if (!dentry) { - iput(inode); - dentry = ERR_PTR(-ENOMEM); + res = d_find_any_alias(inode); + if (res) + goto out_iput; + + tmp = d_alloc(NULL, &anonstring); + if (!tmp) { + res = ERR_PTR(-ENOMEM); + goto out_iput; } - return dentry; + tmp->d_parent = tmp; /* make sure dput doesn't croak */ + + spin_lock(&dcache_lock); + res = __d_find_any_alias(inode); + if (res) { + spin_unlock(&dcache_lock); + dput(tmp); + goto out_iput; + } + + /* attach a disconnected dentry */ + spin_lock(&tmp->d_lock); + tmp->d_sb = inode->i_sb; + tmp->d_inode = inode; + tmp->d_flags |= DCACHE_DISCONNECTED; + tmp->d_flags &= ~DCACHE_UNHASHED; + list_add(&tmp->d_alias, &inode->i_dentry); + hlist_add_head(&tmp->d_hash, &inode->i_sb->s_anon); + spin_unlock(&tmp->d_lock); + + spin_unlock(&dcache_lock); + return tmp; + +out_iput: + iput(inode); + return res; } EXPORT_SYMBOL(d_obtain_alias); @@ -1178,7 +1231,7 @@ struct dentry *d_splice_alias(struct ino { struct dentry *new = NULL; - if (inode) { + if (inode && S_ISDIR(inode->i_mode)) { spin_lock(&dcache_lock); new = __d_find_alias(inode, 1); if (new) { Common subdirectories: linux-2.6.18-238.12.1/fs/debugfs and linux-2.6.18-274.3.1/fs/debugfs Common subdirectories: linux-2.6.18-238.12.1/fs/devpts and linux-2.6.18-274.3.1/fs/devpts Common subdirectories: linux-2.6.18-238.12.1/fs/dlm and linux-2.6.18-274.3.1/fs/dlm diff -up linux-2.6.18-238.12.1/fs/dquot.c linux-2.6.18-274.3.1/fs/dquot.c --- linux-2.6.18-238.12.1/fs/dquot.c 2011-07-05 14:54:24.482615769 +0800 +++ linux-2.6.18-274.3.1/fs/dquot.c 2011-10-21 01:40:04.972943951 +0800 @@ -1819,10 +1819,19 @@ int vfs_get_dqblk(struct super_block *sb EXPORT_SYMBOL(vfs_get_dqblk); /* Generic routine for setting common part of quota structure */ -static void do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) +static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) { struct mem_dqblk *dm = &dquot->dq_dqb; int check_blim = 0, check_ilim = 0; + struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; + + if ((di->dqb_valid & QIF_BLIMITS && + (di->dqb_bhardlimit > DQI_MAXBLIMIT || + di->dqb_bsoftlimit > DQI_MAXBLIMIT)) || + (di->dqb_valid & QIF_ILIMITS && + (di->dqb_ihardlimit > DQI_MAXILIMIT || + di->dqb_isoftlimit > DQI_MAXILIMIT))) + return -ERANGE; spin_lock(&dq_data_lock); if (di->dqb_valid & QIF_SPACE) { @@ -1854,7 +1863,7 @@ static void do_set_dqblk(struct dquot *d clear_bit(DQ_BLKS_B, &dquot->dq_flags); } else if (!(di->dqb_valid & QIF_BTIME)) /* Set grace only if user hasn't provided his own... */ - dm->dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace; + dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; } if (check_ilim) { if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) { @@ -1862,7 +1871,7 @@ static void do_set_dqblk(struct dquot *d clear_bit(DQ_INODES_B, &dquot->dq_flags); } else if (!(di->dqb_valid & QIF_ITIME)) /* Set grace only if user hasn't provided his own... */ - dm->dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; + dm->dqb_itime = get_seconds() + dqi->dqi_igrace; } if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit) clear_bit(DQ_FAKE_B, &dquot->dq_flags); @@ -1870,21 +1879,24 @@ static void do_set_dqblk(struct dquot *d set_bit(DQ_FAKE_B, &dquot->dq_flags); spin_unlock(&dq_data_lock); mark_dquot_dirty(dquot); + + return 0; } int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di) { struct dquot *dquot; + int rc; mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); if (!(dquot = dqget(sb, id, type))) { mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return -ESRCH; } - do_set_dqblk(dquot, di); + rc = do_set_dqblk(dquot, di); dqput(dquot); mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); - return 0; + return rc; } EXPORT_SYMBOL(vfs_set_dqblk); Common subdirectories: linux-2.6.18-238.12.1/fs/ecryptfs and linux-2.6.18-274.3.1/fs/ecryptfs Common subdirectories: linux-2.6.18-238.12.1/fs/efs and linux-2.6.18-274.3.1/fs/efs Common subdirectories: linux-2.6.18-238.12.1/fs/exportfs and linux-2.6.18-274.3.1/fs/exportfs Common subdirectories: linux-2.6.18-238.12.1/fs/ext2 and linux-2.6.18-274.3.1/fs/ext2 Common subdirectories: linux-2.6.18-238.12.1/fs/ext3 and linux-2.6.18-274.3.1/fs/ext3 Common subdirectories: linux-2.6.18-238.12.1/fs/ext4 and linux-2.6.18-274.3.1/fs/ext4 Common subdirectories: linux-2.6.18-238.12.1/fs/fat and linux-2.6.18-274.3.1/fs/fat diff -up linux-2.6.18-238.12.1/fs/file.c linux-2.6.18-274.3.1/fs/file.c --- linux-2.6.18-238.12.1/fs/file.c 2011-06-09 18:00:09.176084781 +0800 +++ linux-2.6.18-274.3.1/fs/file.c 2011-10-21 01:40:05.288945358 +0800 @@ -45,17 +45,20 @@ struct file ** alloc_fd_array(int num) struct file **new_fds; int size = num * sizeof(struct file *); - if (size <= PAGE_SIZE) - new_fds = (struct file **) kmalloc(size, GFP_KERNEL); - else - new_fds = (struct file **) vmalloc(size); + new_fds = (struct file **) kmalloc(size, GFP_KERNEL); + if (new_fds != NULL) + return new_fds; + new_fds = (struct file **) vmalloc(size); return new_fds; } -void free_fd_array(struct file **array, int num) +static void free_fdmem(void *ptr) { - int size = num * sizeof(struct file *); + is_vmalloc_addr(ptr) ? vfree(ptr) : kfree(ptr); +} +void free_fd_array(struct file **array, int num) +{ if (!array) { printk (KERN_ERR "free_fd_array: array = 0 (num = %d)\n", num); return; @@ -63,10 +66,7 @@ void free_fd_array(struct file **array, if (num <= NR_OPEN_DEFAULT) /* Don't free the embedded fd array! */ return; - else if (size <= PAGE_SIZE) - kfree(array); - else - vfree(array); + free_fdmem(array); } static void __free_fdtable(struct fdtable *fdt) @@ -214,10 +214,11 @@ fd_set * alloc_fdset(int num) fd_set *new_fdset; int size = num / 8; - if (size <= PAGE_SIZE) - new_fdset = (fd_set *) kmalloc(size, GFP_KERNEL); - else - new_fdset = (fd_set *) vmalloc(size); + new_fdset = (fd_set *) kmalloc(size, GFP_KERNEL); + if (new_fdset != NULL) + return new_fdset; + + new_fdset = (fd_set *) vmalloc(size); return new_fdset; } @@ -225,10 +226,7 @@ void free_fdset(fd_set *array, int num) { if (num <= EMBEDDED_FD_SET_SIZE) /* Don't free an embedded fdset */ return; - else if (num <= 8 * PAGE_SIZE) - kfree(array); - else - vfree(array); + free_fdmem(array); } static struct fdtable *alloc_fdtable(int nr) Common subdirectories: linux-2.6.18-238.12.1/fs/freevxfs and linux-2.6.18-274.3.1/fs/freevxfs Common subdirectories: linux-2.6.18-238.12.1/fs/fscache and linux-2.6.18-274.3.1/fs/fscache Common subdirectories: linux-2.6.18-238.12.1/fs/fuse and linux-2.6.18-274.3.1/fs/fuse Common subdirectories: linux-2.6.18-238.12.1/fs/gfs2 and linux-2.6.18-274.3.1/fs/gfs2 Common subdirectories: linux-2.6.18-238.12.1/fs/hfs and linux-2.6.18-274.3.1/fs/hfs Common subdirectories: linux-2.6.18-238.12.1/fs/hfsplus and linux-2.6.18-274.3.1/fs/hfsplus Common subdirectories: linux-2.6.18-238.12.1/fs/hostfs and linux-2.6.18-274.3.1/fs/hostfs Common subdirectories: linux-2.6.18-238.12.1/fs/hpfs and linux-2.6.18-274.3.1/fs/hpfs Common subdirectories: linux-2.6.18-238.12.1/fs/hppfs and linux-2.6.18-274.3.1/fs/hppfs Common subdirectories: linux-2.6.18-238.12.1/fs/hugetlbfs and linux-2.6.18-274.3.1/fs/hugetlbfs diff -up linux-2.6.18-238.12.1/fs/ioctl.c linux-2.6.18-274.3.1/fs/ioctl.c --- linux-2.6.18-238.12.1/fs/ioctl.c 2011-06-09 18:00:04.995084779 +0800 +++ linux-2.6.18-274.3.1/fs/ioctl.c 2011-10-21 01:40:06.006948563 +0800 @@ -198,14 +198,23 @@ static int ioctl_fiemap(struct file *fil return error; } -#define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits) -#define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits); +static inline sector_t logical_to_blk(struct inode *inode, loff_t offset) +{ + return (offset >> inode->i_blkbits); +} + +static inline loff_t blk_to_logical(struct inode *inode, sector_t blk) +{ + return (blk << inode->i_blkbits); +} /** * __generic_block_fiemap - FIEMAP for block based inodes (no locking) - * @inode - the inode to map - * @arg - the pointer to userspace where we copy everything to - * @get_block - the fs's get_block function + * @inode: the inode to map + * @fieinfo: the fiemap info struct that will be passed back to userspace + * @start: where to start mapping in the inode + * @len: how much space to map + * @get_block: the fs's get_block function * * This does FIEMAP for block based inodes. Basically it will just loop * through get_block until we hit the number of extents we want to map, or we @@ -220,59 +229,114 @@ static int ioctl_fiemap(struct file *fil */ int __generic_block_fiemap(struct inode *inode, - struct fiemap_extent_info *fieinfo, u64 start, - u64 len, get_block_t *get_block) + struct fiemap_extent_info *fieinfo, loff_t start, + loff_t len, get_block_t *get_block) { - struct buffer_head tmp; - unsigned int start_blk; - long long length = 0, map_len = 0; + struct buffer_head map_bh; + sector_t start_blk, last_blk; + loff_t isize = i_size_read(inode); u64 logical = 0, phys = 0, size = 0; u32 flags = FIEMAP_EXTENT_MERGED; + bool past_eof = false, whole_file = false; int ret = 0; - if ((ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC))) + ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); + if (ret) return ret; - start_blk = logical_to_blk(inode, start); + /* + * Either the i_mutex or other appropriate locking needs to be held + * since we expect isize to not change at all through the duration of + * this call. + */ + if (len >= isize) { + whole_file = true; + len = isize; + } + + /* + * Some filesystems can't deal with being asked to map less than + * blocksize, so make sure our len is at least block length. + */ + if (logical_to_blk(inode, len) == 0) + len = blk_to_logical(inode, 1); - length = (long long)min_t(u64, len, i_size_read(inode)); - map_len = length; + start_blk = logical_to_blk(inode, start); + last_blk = logical_to_blk(inode, start + len - 1); do { /* * we set b_size to the total size we want so it will map as * many contiguous blocks as possible at once */ - memset(&tmp, 0, sizeof(struct buffer_head)); - tmp.b_size = map_len; + memset(&map_bh, 0, sizeof(struct buffer_head)); + map_bh.b_size = len; - ret = get_block(inode, start_blk, &tmp, 0); + ret = get_block(inode, start_blk, &map_bh, 0); if (ret) break; /* HOLE */ - if (!buffer_mapped(&tmp)) { + if (!buffer_mapped(&map_bh)) { + start_blk++; + + /* + * We want to handle the case where there is an + * allocated block at the front of the file, and then + * nothing but holes up to the end of the file properly, + * to make sure that extent at the front gets properly + * marked with FIEMAP_EXTENT_LAST + */ + if (!past_eof && + blk_to_logical(inode, start_blk) >= isize) + past_eof = 1; + /* - * first hole after going past the EOF, this is our + * First hole after going past the EOF, this is our * last extent */ - if (length <= 0) { + if (past_eof && size) { flags = FIEMAP_EXTENT_MERGED|FIEMAP_EXTENT_LAST; ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, flags); - break; + } else if (size) { + ret = fiemap_fill_next_extent(fieinfo, logical, + phys, size, flags); + size = 0; } - length -= blk_to_logical(inode, 1); - /* if we have holes up to/past EOF then we're done */ - if (length <= 0) + if (start_blk > last_blk || past_eof || ret) break; - - start_blk++; } else { - if (length <= 0 && size) { + /* + * We have gone over the length of what we wanted to + * map, and it wasn't the entire file, so add the extent + * we got last time and exit. + * + * This is for the case where say we want to map all the + * way up to the second to the last block in a file, but + * the last block is a hole, making the second to last + * block FIEMAP_EXTENT_LAST. In this case we want to + * see if there is a hole after the second to last block + * so we can mark it properly. If we found data after + * we exceeded the length we were requesting, then we + * are good to go, just add the extent to the fieinfo + * and break + */ + if (start_blk > last_blk && !whole_file) { + ret = fiemap_fill_next_extent(fieinfo, logical, + phys, size, + flags); + break; + } + + /* + * if size != 0 then we know we already have an extent + * to add, so add it. + */ + if (size) { ret = fiemap_fill_next_extent(fieinfo, logical, phys, size, flags); @@ -281,32 +345,24 @@ int __generic_block_fiemap(struct inode } logical = blk_to_logical(inode, start_blk); - phys = blk_to_logical(inode, tmp.b_blocknr); - size = tmp.b_size; + phys = blk_to_logical(inode, map_bh.b_blocknr); + size = map_bh.b_size; flags = FIEMAP_EXTENT_MERGED; - length -= tmp.b_size; start_blk += logical_to_blk(inode, size); /* - * if we are past the EOF we need to loop again to see - * if there is a hole so we can mark this extent as the - * last one, and if not keep mapping things until we - * find a hole, or we run out of slots in the extent - * array + * If we are past the EOF, then we need to make sure as + * soon as we find a hole that the last extent we found + * is marked with FIEMAP_EXTENT_LAST */ - if (length <= 0) - continue; - - ret = fiemap_fill_next_extent(fieinfo, logical, phys, - size, flags); - if (ret) - break; + if (!past_eof && logical + size >= isize) + past_eof = true; } cond_resched(); } while (1); - /* if ret is 1 then we just hit the end of the extent array */ + /* If ret is 1 then we just hit the end of the extent array */ if (ret == 1) ret = 0; Common subdirectories: linux-2.6.18-238.12.1/fs/isofs and linux-2.6.18-274.3.1/fs/isofs Common subdirectories: linux-2.6.18-238.12.1/fs/jbd and linux-2.6.18-274.3.1/fs/jbd Common subdirectories: linux-2.6.18-238.12.1/fs/jbd2 and linux-2.6.18-274.3.1/fs/jbd2 Common subdirectories: linux-2.6.18-238.12.1/fs/jffs and linux-2.6.18-274.3.1/fs/jffs Common subdirectories: linux-2.6.18-238.12.1/fs/jffs2 and linux-2.6.18-274.3.1/fs/jffs2 Common subdirectories: linux-2.6.18-238.12.1/fs/jfs and linux-2.6.18-274.3.1/fs/jfs diff -up linux-2.6.18-238.12.1/fs/Kconfig linux-2.6.18-274.3.1/fs/Kconfig --- linux-2.6.18-238.12.1/fs/Kconfig 2011-07-05 14:54:24.811615770 +0800 +++ linux-2.6.18-274.3.1/fs/Kconfig 2011-10-21 01:40:06.440950498 +0800 @@ -1589,13 +1589,6 @@ config NFS_V4 If unsure, say N. -config NFS_FSCACHE - bool "Provide NFS client caching support (EXPERIMENTAL)" - depends on NFS_FS && FSCACHE && EXPERIMENTAL - help - Say Y here if you want NFS data to be cached locally on disc through - the general filesystem cache manager - config NFS_DIRECTIO bool "Allow direct I/O on NFS files (EXPERIMENTAL)" depends on NFS_FS && EXPERIMENTAL Common subdirectories: linux-2.6.18-238.12.1/fs/lockd and linux-2.6.18-274.3.1/fs/lockd diff -up linux-2.6.18-238.12.1/fs/locks.c linux-2.6.18-274.3.1/fs/locks.c --- linux-2.6.18-238.12.1/fs/locks.c 2011-06-09 18:00:04.381084779 +0800 +++ linux-2.6.18-274.3.1/fs/locks.c 2011-10-21 01:40:06.623951314 +0800 @@ -2122,16 +2122,20 @@ int vfs_cancel_lock(struct file *filp, s } EXPORT_SYMBOL_GPL(vfs_cancel_lock); -static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx) +#ifdef CONFIG_PROC_FS +#include + +static void lock_get_status(struct seq_file *f, struct file_lock *fl, + loff_t id, char *pfx) { struct inode *inode = NULL; if (fl->fl_file != NULL) inode = fl->fl_file->f_dentry->d_inode; - out += sprintf(out, "%d:%s ", id, pfx); + seq_printf(f, "%lld:%s ", id, pfx); if (IS_POSIX(fl)) { - out += sprintf(out, "%6s %s ", + seq_printf(f, "%6s %s ", (fl->fl_flags & FL_ACCESS) ? "ACCESS" : "POSIX ", (inode == NULL) ? "*NOINODE*" : (IS_MANDLOCK(inode) && @@ -2139,121 +2143,98 @@ static void lock_get_status(char* out, s "MANDATORY" : "ADVISORY "); } else if (IS_FLOCK(fl)) { if (fl->fl_type & LOCK_MAND) { - out += sprintf(out, "FLOCK MSNFS "); + seq_printf(f, "FLOCK MSNFS "); } else { - out += sprintf(out, "FLOCK ADVISORY "); + seq_printf(f, "FLOCK ADVISORY "); } } else if (IS_LEASE(fl)) { - out += sprintf(out, "LEASE "); + seq_printf(f, "LEASE "); if (fl->fl_type & F_INPROGRESS) - out += sprintf(out, "BREAKING "); + seq_printf(f, "BREAKING "); else if (fl->fl_file) - out += sprintf(out, "ACTIVE "); + seq_printf(f, "ACTIVE "); else - out += sprintf(out, "BREAKER "); + seq_printf(f, "BREAKER "); } else { - out += sprintf(out, "UNKNOWN UNKNOWN "); + seq_printf(f, "UNKNOWN UNKNOWN "); } if (fl->fl_type & LOCK_MAND) { - out += sprintf(out, "%s ", + seq_printf(f, "%s ", (fl->fl_type & LOCK_READ) ? (fl->fl_type & LOCK_WRITE) ? "RW " : "READ " : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE "); } else { - out += sprintf(out, "%s ", + seq_printf(f, "%s ", (fl->fl_type & F_INPROGRESS) ? (fl->fl_type & F_UNLCK) ? "UNLCK" : "READ " : (fl->fl_type & F_WRLCK) ? "WRITE" : "READ "); } if (inode) { #ifdef WE_CAN_BREAK_LSLK_NOW - out += sprintf(out, "%d %s:%ld ", fl->fl_pid, + seq_printf(f, "%d %s:%ld ", fl->fl_pid, inode->i_sb->s_id, inode->i_ino); #else /* userspace relies on this representation of dev_t ;-( */ - out += sprintf(out, "%d %02x:%02x:%ld ", fl->fl_pid, + seq_printf(f, "%d %02x:%02x:%ld ", fl->fl_pid, MAJOR(inode->i_sb->s_dev), MINOR(inode->i_sb->s_dev), inode->i_ino); #endif } else { - out += sprintf(out, "%d :0 ", fl->fl_pid); + seq_printf(f, "%d :0 ", fl->fl_pid); } if (IS_POSIX(fl)) { if (fl->fl_end == OFFSET_MAX) - out += sprintf(out, "%Ld EOF\n", fl->fl_start); + seq_printf(f, "%Ld EOF\n", fl->fl_start); else - out += sprintf(out, "%Ld %Ld\n", fl->fl_start, - fl->fl_end); + seq_printf(f, "%Ld %Ld\n", fl->fl_start, fl->fl_end); } else { - out += sprintf(out, "0 EOF\n"); + seq_printf(f, "0 EOF\n"); } } -static void move_lock_status(char **p, off_t* pos, off_t offset) +static int locks_show(struct seq_file *f, void *v) { - int len; - len = strlen(*p); - if(*pos >= offset) { - /* the complete line is valid */ - *p += len; - *pos += len; - return; - } - if(*pos+len > offset) { - /* use the second part of the line */ - int i = offset-*pos; - memmove(*p,*p+i,len-i); - *p += len-i; - *pos += len; - return; - } - /* discard the complete line */ - *pos += len; -} + struct file_lock *fl, *bfl; -/** - * get_locks_status - reports lock usage in /proc/locks - * @buffer: address in userspace to write into - * @start: ? - * @offset: how far we are through the buffer - * @length: how much to read - */ + fl = list_entry(v, struct file_lock, fl_link); + + lock_get_status(f, fl, *((loff_t *)f->private), ""); + + list_for_each_entry(bfl, &fl->fl_block, fl_block) + lock_get_status(f, bfl, *((loff_t *)f->private), " ->"); + + return 0; +} -int get_locks_status(char *buffer, char **start, off_t offset, int length) +static void *locks_start(struct seq_file *f, loff_t *pos) { - struct list_head *tmp; - char *q = buffer; - off_t pos = 0; - int i = 0; + loff_t *p = f->private; lock_kernel(); - list_for_each(tmp, &file_lock_list) { - struct list_head *btmp; - struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link); - lock_get_status(q, fl, ++i, ""); - move_lock_status(&q, &pos, offset); - - if(pos >= offset+length) - goto done; - - list_for_each(btmp, &fl->fl_block) { - struct file_lock *bfl = list_entry(btmp, - struct file_lock, fl_block); - lock_get_status(q, bfl, i, " ->"); - move_lock_status(&q, &pos, offset); + *p = (*pos + 1); + return seq_list_start(&file_lock_list, *pos); +} - if(pos >= offset+length) - goto done; - } - } -done: +static void *locks_next(struct seq_file *f, void *v, loff_t *pos) +{ + loff_t *p = f->private; + ++*p; + return seq_list_next(v, &file_lock_list, pos); +} + +static void locks_stop(struct seq_file *f, void *v) +{ unlock_kernel(); - *start = buffer; - if(q-buffer < length) - return (q-buffer); - return length; } +struct seq_operations locks_seq_operations = { + .start = locks_start, + .next = locks_next, + .stop = locks_stop, + .show = locks_show, +}; +#endif + /** * lock_may_read - checks that the region is free of locks * @inode: the inode that is being read Common subdirectories: linux-2.6.18-238.12.1/fs/minix and linux-2.6.18-274.3.1/fs/minix diff -up linux-2.6.18-238.12.1/fs/mpage.c linux-2.6.18-274.3.1/fs/mpage.c --- linux-2.6.18-238.12.1/fs/mpage.c 2011-06-09 18:00:08.119084781 +0800 +++ linux-2.6.18-274.3.1/fs/mpage.c 2011-10-21 01:40:06.698951649 +0800 @@ -80,7 +80,6 @@ static int mpage_end_io_write(struct bio prefetchw(&bvec->bv_page->flags); if (!uptodate){ - SetPageError(page); if (page->mapping) set_bit(AS_EIO, &page->mapping->flags); } Common subdirectories: linux-2.6.18-238.12.1/fs/msdos and linux-2.6.18-274.3.1/fs/msdos Common subdirectories: linux-2.6.18-238.12.1/fs/ncpfs and linux-2.6.18-274.3.1/fs/ncpfs Common subdirectories: linux-2.6.18-238.12.1/fs/nfs and linux-2.6.18-274.3.1/fs/nfs Common subdirectories: linux-2.6.18-238.12.1/fs/nfs_common and linux-2.6.18-274.3.1/fs/nfs_common Common subdirectories: linux-2.6.18-238.12.1/fs/nfsd and linux-2.6.18-274.3.1/fs/nfsd Common subdirectories: linux-2.6.18-238.12.1/fs/nls and linux-2.6.18-274.3.1/fs/nls Common subdirectories: linux-2.6.18-238.12.1/fs/ntfs and linux-2.6.18-274.3.1/fs/ntfs Common subdirectories: linux-2.6.18-238.12.1/fs/ocfs2 and linux-2.6.18-274.3.1/fs/ocfs2 Common subdirectories: linux-2.6.18-238.12.1/fs/openpromfs and linux-2.6.18-274.3.1/fs/openpromfs Common subdirectories: linux-2.6.18-238.12.1/fs/partitions and linux-2.6.18-274.3.1/fs/partitions Common subdirectories: linux-2.6.18-238.12.1/fs/proc and linux-2.6.18-274.3.1/fs/proc Common subdirectories: linux-2.6.18-238.12.1/fs/qnx4 and linux-2.6.18-274.3.1/fs/qnx4 Common subdirectories: linux-2.6.18-238.12.1/fs/ramfs and linux-2.6.18-274.3.1/fs/ramfs Common subdirectories: linux-2.6.18-238.12.1/fs/reiserfs and linux-2.6.18-274.3.1/fs/reiserfs Common subdirectories: linux-2.6.18-238.12.1/fs/romfs and linux-2.6.18-274.3.1/fs/romfs diff -up linux-2.6.18-238.12.1/fs/select.c linux-2.6.18-274.3.1/fs/select.c --- linux-2.6.18-238.12.1/fs/select.c 2011-06-09 17:59:47.152084771 +0800 +++ linux-2.6.18-274.3.1/fs/select.c 2011-10-21 01:40:11.615973581 +0800 @@ -132,6 +132,34 @@ static void __pollwait(struct file *filp add_wait_queue(wait_address,&entry->wait); } +/** + * poll_select_set_timeout - helper function to setup the timeout value + * @to: pointer to timespec variable for the final timeout + * @sec: seconds (from user space) + * @nsec: nanoseconds (from user space) + * + * Note, we do not use a timespec for the user space value here, That + * way we can use the function for timeval and compat interfaces as well. + * + * Returns -EINVAL if sec/nsec are not normalized. Otherwise 0. + */ +int poll_select_set_timeout(struct timespec *to, long sec, long nsec) +{ + struct timespec ts = {.tv_sec = sec, .tv_nsec = nsec}; + + if (!timespec_valid(&ts)) + return -EINVAL; + + /* Optimize for the zero timeout value here */ + if (!sec && !nsec) { + to->tv_sec = to->tv_nsec = 0; + } else { + ktime_get_ts(to); + *to = timespec_add_safe(*to, ts); + } + return 0; +} + #define FDS_IN(fds, n) (fds->in + n) #define FDS_OUT(fds, n) (fds->out + n) #define FDS_EX(fds, n) (fds->ex + n) @@ -400,7 +428,7 @@ asmlinkage long sys_select(int n, fd_set timeout = -1; /* infinite */ else { timeout = ROUND_UP(tv.tv_usec, USEC_PER_SEC/HZ); - timeout += tv.tv_sec * HZ; + timeout += (s64)tv.tv_sec * HZ; } } @@ -455,7 +483,7 @@ asmlinkage long sys_pselect7(int n, fd_s timeout = -1; /* infinite */ else { timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ); - timeout += ts.tv_sec * HZ; + timeout += (s64)ts.tv_sec * HZ; } } @@ -777,7 +805,7 @@ asmlinkage long sys_ppoll(struct pollfd timeout = -1; /* infinite */ else { timeout = ROUND_UP(ts.tv_nsec, NSEC_PER_SEC/HZ); - timeout += ts.tv_sec * HZ; + timeout += (s64)ts.tv_sec * HZ; } } diff -up linux-2.6.18-238.12.1/fs/seq_file.c linux-2.6.18-274.3.1/fs/seq_file.c --- linux-2.6.18-238.12.1/fs/seq_file.c 2006-09-20 11:42:06.000000000 +0800 +++ linux-2.6.18-274.3.1/fs/seq_file.c 2011-10-21 01:40:11.726974076 +0800 @@ -425,6 +425,39 @@ int seq_release_private(struct inode *in } EXPORT_SYMBOL(seq_release_private); +void *__seq_open_private(struct file *f, const struct seq_operations *ops, + int psize) +{ + int rc; + void *private; + struct seq_file *seq; + + private = kzalloc(psize, GFP_KERNEL); + if (private == NULL) + goto out; + + rc = seq_open(f, ops); + if (rc < 0) + goto out_free; + + seq = f->private_data; + seq->private = private; + return private; + +out_free: + kfree(private); +out: + return NULL; +} +EXPORT_SYMBOL(__seq_open_private); + +int seq_open_private(struct file *filp, const struct seq_operations *ops, + int psize) +{ + return __seq_open_private(filp, ops, psize) ? 0 : -ENOMEM; +} +EXPORT_SYMBOL(seq_open_private); + int seq_putc(struct seq_file *m, char c) { if (m->count < m->size) { @@ -447,3 +480,37 @@ int seq_puts(struct seq_file *m, const c return -1; } EXPORT_SYMBOL(seq_puts); + +struct list_head *seq_list_start(struct list_head *head, loff_t pos) +{ + struct list_head *lh; + + list_for_each(lh, head) + if (pos-- == 0) + return lh; + + return NULL; +} + +EXPORT_SYMBOL(seq_list_start); + +struct list_head *seq_list_start_head(struct list_head *head, loff_t pos) +{ + if (!pos) + return head; + + return seq_list_start(head, pos - 1); +} + +EXPORT_SYMBOL(seq_list_start_head); + +struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos) +{ + struct list_head *lh; + + lh = ((struct list_head *)v)->next; + ++*ppos; + return lh == head ? NULL : lh; +} + +EXPORT_SYMBOL(seq_list_next); Common subdirectories: linux-2.6.18-238.12.1/fs/smbfs and linux-2.6.18-274.3.1/fs/smbfs Common subdirectories: linux-2.6.18-238.12.1/fs/squashfs and linux-2.6.18-274.3.1/fs/squashfs diff -up linux-2.6.18-238.12.1/fs/stat.c linux-2.6.18-274.3.1/fs/stat.c --- linux-2.6.18-238.12.1/fs/stat.c 2011-06-09 18:00:13.056084783 +0800 +++ linux-2.6.18-274.3.1/fs/stat.c 2011-10-21 01:40:12.273976516 +0800 @@ -33,7 +33,7 @@ void generic_fillattr(struct inode *inod stat->ctime = inode->i_ctime; stat->size = i_size_read(inode); stat->blocks = inode->i_blocks; - stat->blksize = PAGE_CACHE_SIZE; + stat->blksize = (1 << inode->i_blkbits); } EXPORT_SYMBOL(generic_fillattr); Common subdirectories: linux-2.6.18-238.12.1/fs/sysfs and linux-2.6.18-274.3.1/fs/sysfs Common subdirectories: linux-2.6.18-238.12.1/fs/sysv and linux-2.6.18-274.3.1/fs/sysv Common subdirectories: linux-2.6.18-238.12.1/fs/udf and linux-2.6.18-274.3.1/fs/udf Common subdirectories: linux-2.6.18-238.12.1/fs/ufs and linux-2.6.18-274.3.1/fs/ufs Common subdirectories: linux-2.6.18-238.12.1/fs/vfat and linux-2.6.18-274.3.1/fs/vfat Common subdirectories: linux-2.6.18-238.12.1/fs/xfs and linux-2.6.18-274.3.1/fs/xfs