diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-11 19:01:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-11 19:01:34 -0400 |
commit | 886c81834884ed3df0d8cfc613d65441226786c8 (patch) | |
tree | d3f6358a94e99bdc8d29acffe461d2ad33812057 /fs | |
parent | dc8a7b11aa68d6795a46e0a42ce92220d1a6f0cd (diff) | |
parent | e0dceaf0a4b8c55076a4dbcba7ac8b05755f5cc6 (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2:
ocfs2: set non-default s_time_gran during mount
ocfs2: Retry sendpage() if it returns EAGAIN
ocfs2: Fix rename/extend race
[2.6 patch] ocfs2_insert_extent(): remove dead code
ocfs2: Fix max offset calculations
ocfs2: check ia_size limits in setattr
ocfs2: Fix some casting errors related to file writes
ocfs2: use s_maxbytes directly in ocfs2_change_file_space()
ocfs2: Restrict inode changes in ocfs2_update_inode_atime()
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ocfs2/alloc.c | 4 | ||||
-rw-r--r-- | fs/ocfs2/cluster/tcp.c | 24 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 28 | ||||
-rw-r--r-- | fs/ocfs2/namei.c | 16 | ||||
-rw-r--r-- | fs/ocfs2/ocfs2.h | 8 | ||||
-rw-r--r-- | fs/ocfs2/super.c | 69 | ||||
-rw-r--r-- | fs/ocfs2/super.h | 2 |
7 files changed, 101 insertions, 50 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index f5e11f4fa952..4f517665c9a0 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -3731,7 +3731,6 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
3731 | { | 3731 | { |
3732 | int status; | 3732 | int status; |
3733 | struct buffer_head *last_eb_bh = NULL; | 3733 | struct buffer_head *last_eb_bh = NULL; |
3734 | struct buffer_head *bh = NULL; | ||
3735 | struct ocfs2_insert_type insert = {0, }; | 3734 | struct ocfs2_insert_type insert = {0, }; |
3736 | struct ocfs2_extent_rec rec; | 3735 | struct ocfs2_extent_rec rec; |
3737 | 3736 | ||
@@ -3783,9 +3782,6 @@ int ocfs2_insert_extent(struct ocfs2_super *osb, | |||
3783 | ocfs2_extent_map_insert_rec(inode, &rec); | 3782 | ocfs2_extent_map_insert_rec(inode, &rec); |
3784 | 3783 | ||
3785 | bail: | 3784 | bail: |
3786 | if (bh) | ||
3787 | brelse(bh); | ||
3788 | |||
3789 | if (last_eb_bh) | 3785 | if (last_eb_bh) |
3790 | brelse(last_eb_bh); | 3786 | brelse(last_eb_bh); |
3791 | 3787 | ||
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index f0bdfd944c44..685c18065c82 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -854,17 +854,25 @@ static void o2net_sendpage(struct o2net_sock_container *sc, | |||
854 | struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); | 854 | struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); |
855 | ssize_t ret; | 855 | ssize_t ret; |
856 | 856 | ||
857 | 857 | while (1) { | |
858 | mutex_lock(&sc->sc_send_lock); | 858 | mutex_lock(&sc->sc_send_lock); |
859 | ret = sc->sc_sock->ops->sendpage(sc->sc_sock, | 859 | ret = sc->sc_sock->ops->sendpage(sc->sc_sock, |
860 | virt_to_page(kmalloced_virt), | 860 | virt_to_page(kmalloced_virt), |
861 | (long)kmalloced_virt & ~PAGE_MASK, | 861 | (long)kmalloced_virt & ~PAGE_MASK, |
862 | size, MSG_DONTWAIT); | 862 | size, MSG_DONTWAIT); |
863 | mutex_unlock(&sc->sc_send_lock); | 863 | mutex_unlock(&sc->sc_send_lock); |
864 | if (ret != size) { | 864 | if (ret == size) |
865 | break; | ||
866 | if (ret == (ssize_t)-EAGAIN) { | ||
867 | mlog(0, "sendpage of size %zu to " SC_NODEF_FMT | ||
868 | " returned EAGAIN\n", size, SC_NODEF_ARGS(sc)); | ||
869 | cond_resched(); | ||
870 | continue; | ||
871 | } | ||
865 | mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT | 872 | mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT |
866 | " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret); | 873 | " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret); |
867 | o2net_ensure_shutdown(nn, sc, 0); | 874 | o2net_ensure_shutdown(nn, sc, 0); |
875 | break; | ||
868 | } | 876 | } |
869 | } | 877 | } |
870 | 878 | ||
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index c4034f693e7b..4ffa715be09c 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -187,6 +187,7 @@ int ocfs2_update_inode_atime(struct inode *inode, | |||
187 | int ret; | 187 | int ret; |
188 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 188 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
189 | handle_t *handle; | 189 | handle_t *handle; |
190 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) bh->b_data; | ||
190 | 191 | ||
191 | mlog_entry_void(); | 192 | mlog_entry_void(); |
192 | 193 | ||
@@ -197,11 +198,27 @@ int ocfs2_update_inode_atime(struct inode *inode, | |||
197 | goto out; | 198 | goto out; |
198 | } | 199 | } |
199 | 200 | ||
201 | ret = ocfs2_journal_access(handle, inode, bh, | ||
202 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
203 | if (ret) { | ||
204 | mlog_errno(ret); | ||
205 | goto out_commit; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * Don't use ocfs2_mark_inode_dirty() here as we don't always | ||
210 | * have i_mutex to guard against concurrent changes to other | ||
211 | * inode fields. | ||
212 | */ | ||
200 | inode->i_atime = CURRENT_TIME; | 213 | inode->i_atime = CURRENT_TIME; |
201 | ret = ocfs2_mark_inode_dirty(handle, inode, bh); | 214 | di->i_atime = cpu_to_le64(inode->i_atime.tv_sec); |
215 | di->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec); | ||
216 | |||
217 | ret = ocfs2_journal_dirty(handle, bh); | ||
202 | if (ret < 0) | 218 | if (ret < 0) |
203 | mlog_errno(ret); | 219 | mlog_errno(ret); |
204 | 220 | ||
221 | out_commit: | ||
205 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 222 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
206 | out: | 223 | out: |
207 | mlog_exit(ret); | 224 | mlog_exit(ret); |
@@ -1011,6 +1028,11 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1011 | } | 1028 | } |
1012 | 1029 | ||
1013 | if (size_change && attr->ia_size != i_size_read(inode)) { | 1030 | if (size_change && attr->ia_size != i_size_read(inode)) { |
1031 | if (attr->ia_size > sb->s_maxbytes) { | ||
1032 | status = -EFBIG; | ||
1033 | goto bail_unlock; | ||
1034 | } | ||
1035 | |||
1014 | if (i_size_read(inode) > attr->ia_size) | 1036 | if (i_size_read(inode) > attr->ia_size) |
1015 | status = ocfs2_truncate_file(inode, bh, attr->ia_size); | 1037 | status = ocfs2_truncate_file(inode, bh, attr->ia_size); |
1016 | else | 1038 | else |
@@ -1516,7 +1538,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode, | |||
1516 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1538 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
1517 | struct buffer_head *di_bh = NULL; | 1539 | struct buffer_head *di_bh = NULL; |
1518 | handle_t *handle; | 1540 | handle_t *handle; |
1519 | unsigned long long max_off = ocfs2_max_file_offset(inode->i_sb->s_blocksize_bits); | 1541 | unsigned long long max_off = inode->i_sb->s_maxbytes; |
1520 | 1542 | ||
1521 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) | 1543 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) |
1522 | return -EROFS; | 1544 | return -EROFS; |
@@ -1942,7 +1964,7 @@ static ssize_t ocfs2_file_buffered_write(struct file *file, loff_t *ppos, | |||
1942 | } | 1964 | } |
1943 | 1965 | ||
1944 | dst = kmap_atomic(page, KM_USER0); | 1966 | dst = kmap_atomic(page, KM_USER0); |
1945 | memcpy(dst + (pos & (PAGE_CACHE_SIZE - 1)), buf, bytes); | 1967 | memcpy(dst + (pos & (loff_t)(PAGE_CACHE_SIZE - 1)), buf, bytes); |
1946 | kunmap_atomic(dst, KM_USER0); | 1968 | kunmap_atomic(dst, KM_USER0); |
1947 | flush_dcache_page(page); | 1969 | flush_dcache_page(page); |
1948 | ocfs2_put_write_source(user_page); | 1970 | ocfs2_put_write_source(user_page); |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index d430fdab16e9..701e6d04ed5d 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -1080,6 +1080,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1080 | struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, | 1080 | struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, |
1081 | // this is the 1st dirent bh | 1081 | // this is the 1st dirent bh |
1082 | nlink_t old_dir_nlink = old_dir->i_nlink; | 1082 | nlink_t old_dir_nlink = old_dir->i_nlink; |
1083 | struct ocfs2_dinode *old_di; | ||
1083 | 1084 | ||
1084 | /* At some point it might be nice to break this function up a | 1085 | /* At some point it might be nice to break this function up a |
1085 | * bit. */ | 1086 | * bit. */ |
@@ -1354,7 +1355,20 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1354 | 1355 | ||
1355 | old_inode->i_ctime = CURRENT_TIME; | 1356 | old_inode->i_ctime = CURRENT_TIME; |
1356 | mark_inode_dirty(old_inode); | 1357 | mark_inode_dirty(old_inode); |
1357 | ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh); | 1358 | |
1359 | status = ocfs2_journal_access(handle, old_inode, old_inode_bh, | ||
1360 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
1361 | if (status >= 0) { | ||
1362 | old_di = (struct ocfs2_dinode *) old_inode_bh->b_data; | ||
1363 | |||
1364 | old_di->i_ctime = cpu_to_le64(old_inode->i_ctime.tv_sec); | ||
1365 | old_di->i_ctime_nsec = cpu_to_le32(old_inode->i_ctime.tv_nsec); | ||
1366 | |||
1367 | status = ocfs2_journal_dirty(handle, old_inode_bh); | ||
1368 | if (status < 0) | ||
1369 | mlog_errno(status); | ||
1370 | } else | ||
1371 | mlog_errno(status); | ||
1358 | 1372 | ||
1359 | /* now that the name has been added to new_dir, remove the old name */ | 1373 | /* now that the name has been added to new_dir, remove the old name */ |
1360 | status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh); | 1374 | status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh); |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 5cc90a40b3c5..58307853fb4a 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -494,16 +494,16 @@ static inline unsigned int ocfs2_page_index_to_clusters(struct super_block *sb, | |||
494 | /* | 494 | /* |
495 | * Find the 1st page index which covers the given clusters. | 495 | * Find the 1st page index which covers the given clusters. |
496 | */ | 496 | */ |
497 | static inline unsigned long ocfs2_align_clusters_to_page_index(struct super_block *sb, | 497 | static inline pgoff_t ocfs2_align_clusters_to_page_index(struct super_block *sb, |
498 | u32 clusters) | 498 | u32 clusters) |
499 | { | 499 | { |
500 | unsigned int cbits = OCFS2_SB(sb)->s_clustersize_bits; | 500 | unsigned int cbits = OCFS2_SB(sb)->s_clustersize_bits; |
501 | unsigned long index = clusters; | 501 | pgoff_t index = clusters; |
502 | 502 | ||
503 | if (PAGE_CACHE_SHIFT > cbits) { | 503 | if (PAGE_CACHE_SHIFT > cbits) { |
504 | index = clusters >> (PAGE_CACHE_SHIFT - cbits); | 504 | index = (pgoff_t)clusters >> (PAGE_CACHE_SHIFT - cbits); |
505 | } else if (PAGE_CACHE_SHIFT < cbits) { | 505 | } else if (PAGE_CACHE_SHIFT < cbits) { |
506 | index = clusters << (cbits - PAGE_CACHE_SHIFT); | 506 | index = (pgoff_t)clusters << (cbits - PAGE_CACHE_SHIFT); |
507 | } | 507 | } |
508 | 508 | ||
509 | return index; | 509 | return index; |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 200c7d4790dc..f2fc9a795deb 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -316,39 +316,51 @@ static void ocfs2_destroy_inode(struct inode *inode) | |||
316 | kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode)); | 316 | kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode)); |
317 | } | 317 | } |
318 | 318 | ||
319 | /* From xfs_super.c:xfs_max_file_offset | 319 | static unsigned long long ocfs2_max_file_offset(unsigned int bbits, |
320 | * Copyright (c) 2000-2004 Silicon Graphics, Inc. | 320 | unsigned int cbits) |
321 | */ | ||
322 | unsigned long long ocfs2_max_file_offset(unsigned int blockshift) | ||
323 | { | 321 | { |
324 | unsigned int pagefactor = 1; | 322 | unsigned int bytes = 1 << cbits; |
325 | unsigned int bitshift = BITS_PER_LONG - 1; | 323 | unsigned int trim = bytes; |
326 | 324 | unsigned int bitshift = 32; | |
327 | /* Figure out maximum filesize, on Linux this can depend on | 325 | |
328 | * the filesystem blocksize (on 32 bit platforms). | 326 | /* |
329 | * __block_prepare_write does this in an [unsigned] long... | 327 | * i_size and all block offsets in ocfs2 are always 64 bits |
330 | * page->index << (PAGE_CACHE_SHIFT - bbits) | 328 | * wide. i_clusters is 32 bits, in cluster-sized units. So on |
331 | * So, for page sized blocks (4K on 32 bit platforms), | 329 | * 64 bit platforms, cluster size will be the limiting factor. |
332 | * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is | ||
333 | * (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) | ||
334 | * but for smaller blocksizes it is less (bbits = log2 bsize). | ||
335 | * Note1: get_block_t takes a long (implicit cast from above) | ||
336 | * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch | ||
337 | * can optionally convert the [unsigned] long from above into | ||
338 | * an [unsigned] long long. | ||
339 | */ | 330 | */ |
340 | 331 | ||
341 | #if BITS_PER_LONG == 32 | 332 | #if BITS_PER_LONG == 32 |
342 | # if defined(CONFIG_LBD) | 333 | # if defined(CONFIG_LBD) |
343 | BUILD_BUG_ON(sizeof(sector_t) != 8); | 334 | BUILD_BUG_ON(sizeof(sector_t) != 8); |
344 | pagefactor = PAGE_CACHE_SIZE; | 335 | /* |
345 | bitshift = BITS_PER_LONG; | 336 | * We might be limited by page cache size. |
337 | */ | ||
338 | if (bytes > PAGE_CACHE_SIZE) { | ||
339 | bytes = PAGE_CACHE_SIZE; | ||
340 | trim = 1; | ||
341 | /* | ||
342 | * Shift by 31 here so that we don't get larger than | ||
343 | * MAX_LFS_FILESIZE | ||
344 | */ | ||
345 | bitshift = 31; | ||
346 | } | ||
346 | # else | 347 | # else |
347 | pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift); | 348 | /* |
349 | * We are limited by the size of sector_t. Use block size, as | ||
350 | * that's what we expose to the VFS. | ||
351 | */ | ||
352 | bytes = 1 << bbits; | ||
353 | trim = 1; | ||
354 | bitshift = 31; | ||
348 | # endif | 355 | # endif |
349 | #endif | 356 | #endif |
350 | 357 | ||
351 | return (((unsigned long long)pagefactor) << bitshift) - 1; | 358 | /* |
359 | * Trim by a whole cluster when we can actually approach the | ||
360 | * on-disk limits. Otherwise we can overflow i_clusters when | ||
361 | * an extent start is at the max offset. | ||
362 | */ | ||
363 | return (((unsigned long long)bytes) << bitshift) - trim; | ||
352 | } | 364 | } |
353 | 365 | ||
354 | static int ocfs2_remount(struct super_block *sb, int *flags, char *data) | 366 | static int ocfs2_remount(struct super_block *sb, int *flags, char *data) |
@@ -1259,8 +1271,8 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1259 | int sector_size) | 1271 | int sector_size) |
1260 | { | 1272 | { |
1261 | int status = 0; | 1273 | int status = 0; |
1262 | int i; | 1274 | int i, cbits, bbits; |
1263 | struct ocfs2_dinode *di = NULL; | 1275 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; |
1264 | struct inode *inode = NULL; | 1276 | struct inode *inode = NULL; |
1265 | struct buffer_head *bitmap_bh = NULL; | 1277 | struct buffer_head *bitmap_bh = NULL; |
1266 | struct ocfs2_journal *journal; | 1278 | struct ocfs2_journal *journal; |
@@ -1279,9 +1291,12 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1279 | sb->s_fs_info = osb; | 1291 | sb->s_fs_info = osb; |
1280 | sb->s_op = &ocfs2_sops; | 1292 | sb->s_op = &ocfs2_sops; |
1281 | sb->s_export_op = &ocfs2_export_ops; | 1293 | sb->s_export_op = &ocfs2_export_ops; |
1294 | sb->s_time_gran = 1; | ||
1282 | sb->s_flags |= MS_NOATIME; | 1295 | sb->s_flags |= MS_NOATIME; |
1283 | /* this is needed to support O_LARGEFILE */ | 1296 | /* this is needed to support O_LARGEFILE */ |
1284 | sb->s_maxbytes = ocfs2_max_file_offset(sb->s_blocksize_bits); | 1297 | cbits = le32_to_cpu(di->id2.i_super.s_clustersize_bits); |
1298 | bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits); | ||
1299 | sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits); | ||
1285 | 1300 | ||
1286 | osb->sb = sb; | 1301 | osb->sb = sb; |
1287 | /* Save off for ocfs2_rw_direct */ | 1302 | /* Save off for ocfs2_rw_direct */ |
@@ -1341,8 +1356,6 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1341 | goto bail; | 1356 | goto bail; |
1342 | } | 1357 | } |
1343 | 1358 | ||
1344 | di = (struct ocfs2_dinode *)bh->b_data; | ||
1345 | |||
1346 | osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots); | 1359 | osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots); |
1347 | if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) { | 1360 | if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) { |
1348 | mlog(ML_ERROR, "Invalid number of node slots (%u)\n", | 1361 | mlog(ML_ERROR, "Invalid number of node slots (%u)\n", |
diff --git a/fs/ocfs2/super.h b/fs/ocfs2/super.h index 3b9cb3d0b008..783f5270f2a1 100644 --- a/fs/ocfs2/super.h +++ b/fs/ocfs2/super.h | |||
@@ -45,6 +45,4 @@ void __ocfs2_abort(struct super_block *sb, | |||
45 | 45 | ||
46 | #define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args) | 46 | #define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args) |
47 | 47 | ||
48 | unsigned long long ocfs2_max_file_offset(unsigned int blockshift); | ||
49 | |||
50 | #endif /* OCFS2_SUPER_H */ | 48 | #endif /* OCFS2_SUPER_H */ |