mirror of https://gitee.com/openkylin/linux.git
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()
This commit is contained in:
commit
886c818348
|
@ -3731,7 +3731,6 @@ int ocfs2_insert_extent(struct ocfs2_super *osb,
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
struct buffer_head *last_eb_bh = NULL;
|
struct buffer_head *last_eb_bh = NULL;
|
||||||
struct buffer_head *bh = NULL;
|
|
||||||
struct ocfs2_insert_type insert = {0, };
|
struct ocfs2_insert_type insert = {0, };
|
||||||
struct ocfs2_extent_rec rec;
|
struct ocfs2_extent_rec rec;
|
||||||
|
|
||||||
|
@ -3783,9 +3782,6 @@ int ocfs2_insert_extent(struct ocfs2_super *osb,
|
||||||
ocfs2_extent_map_insert_rec(inode, &rec);
|
ocfs2_extent_map_insert_rec(inode, &rec);
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
if (bh)
|
|
||||||
brelse(bh);
|
|
||||||
|
|
||||||
if (last_eb_bh)
|
if (last_eb_bh)
|
||||||
brelse(last_eb_bh);
|
brelse(last_eb_bh);
|
||||||
|
|
||||||
|
|
|
@ -854,17 +854,25 @@ static void o2net_sendpage(struct o2net_sock_container *sc,
|
||||||
struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
|
struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
mutex_lock(&sc->sc_send_lock);
|
mutex_lock(&sc->sc_send_lock);
|
||||||
ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
|
ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
|
||||||
virt_to_page(kmalloced_virt),
|
virt_to_page(kmalloced_virt),
|
||||||
(long)kmalloced_virt & ~PAGE_MASK,
|
(long)kmalloced_virt & ~PAGE_MASK,
|
||||||
size, MSG_DONTWAIT);
|
size, MSG_DONTWAIT);
|
||||||
mutex_unlock(&sc->sc_send_lock);
|
mutex_unlock(&sc->sc_send_lock);
|
||||||
if (ret != size) {
|
if (ret == size)
|
||||||
|
break;
|
||||||
|
if (ret == (ssize_t)-EAGAIN) {
|
||||||
|
mlog(0, "sendpage of size %zu to " SC_NODEF_FMT
|
||||||
|
" returned EAGAIN\n", size, SC_NODEF_ARGS(sc));
|
||||||
|
cond_resched();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT
|
mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT
|
||||||
" failed with %zd\n", size, SC_NODEF_ARGS(sc), ret);
|
" failed with %zd\n", size, SC_NODEF_ARGS(sc), ret);
|
||||||
o2net_ensure_shutdown(nn, sc, 0);
|
o2net_ensure_shutdown(nn, sc, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,7 @@ int ocfs2_update_inode_atime(struct inode *inode,
|
||||||
int ret;
|
int ret;
|
||||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||||
handle_t *handle;
|
handle_t *handle;
|
||||||
|
struct ocfs2_dinode *di = (struct ocfs2_dinode *) bh->b_data;
|
||||||
|
|
||||||
mlog_entry_void();
|
mlog_entry_void();
|
||||||
|
|
||||||
|
@ -197,11 +198,27 @@ int ocfs2_update_inode_atime(struct inode *inode,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = ocfs2_journal_access(handle, inode, bh,
|
||||||
|
OCFS2_JOURNAL_ACCESS_WRITE);
|
||||||
|
if (ret) {
|
||||||
|
mlog_errno(ret);
|
||||||
|
goto out_commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't use ocfs2_mark_inode_dirty() here as we don't always
|
||||||
|
* have i_mutex to guard against concurrent changes to other
|
||||||
|
* inode fields.
|
||||||
|
*/
|
||||||
inode->i_atime = CURRENT_TIME;
|
inode->i_atime = CURRENT_TIME;
|
||||||
ret = ocfs2_mark_inode_dirty(handle, inode, bh);
|
di->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
|
||||||
|
di->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
|
||||||
|
|
||||||
|
ret = ocfs2_journal_dirty(handle, bh);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
|
|
||||||
|
out_commit:
|
||||||
ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
|
ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
|
||||||
out:
|
out:
|
||||||
mlog_exit(ret);
|
mlog_exit(ret);
|
||||||
|
@ -1011,6 +1028,11 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size_change && attr->ia_size != i_size_read(inode)) {
|
if (size_change && attr->ia_size != i_size_read(inode)) {
|
||||||
|
if (attr->ia_size > sb->s_maxbytes) {
|
||||||
|
status = -EFBIG;
|
||||||
|
goto bail_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
if (i_size_read(inode) > attr->ia_size)
|
if (i_size_read(inode) > attr->ia_size)
|
||||||
status = ocfs2_truncate_file(inode, bh, attr->ia_size);
|
status = ocfs2_truncate_file(inode, bh, attr->ia_size);
|
||||||
else
|
else
|
||||||
|
@ -1516,7 +1538,7 @@ static int __ocfs2_change_file_space(struct file *file, struct inode *inode,
|
||||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||||
struct buffer_head *di_bh = NULL;
|
struct buffer_head *di_bh = NULL;
|
||||||
handle_t *handle;
|
handle_t *handle;
|
||||||
unsigned long long max_off = ocfs2_max_file_offset(inode->i_sb->s_blocksize_bits);
|
unsigned long long max_off = inode->i_sb->s_maxbytes;
|
||||||
|
|
||||||
if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb))
|
if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb))
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
|
@ -1942,7 +1964,7 @@ static ssize_t ocfs2_file_buffered_write(struct file *file, loff_t *ppos,
|
||||||
}
|
}
|
||||||
|
|
||||||
dst = kmap_atomic(page, KM_USER0);
|
dst = kmap_atomic(page, KM_USER0);
|
||||||
memcpy(dst + (pos & (PAGE_CACHE_SIZE - 1)), buf, bytes);
|
memcpy(dst + (pos & (loff_t)(PAGE_CACHE_SIZE - 1)), buf, bytes);
|
||||||
kunmap_atomic(dst, KM_USER0);
|
kunmap_atomic(dst, KM_USER0);
|
||||||
flush_dcache_page(page);
|
flush_dcache_page(page);
|
||||||
ocfs2_put_write_source(user_page);
|
ocfs2_put_write_source(user_page);
|
||||||
|
|
|
@ -1080,6 +1080,7 @@ static int ocfs2_rename(struct inode *old_dir,
|
||||||
struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
|
struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
|
||||||
// this is the 1st dirent bh
|
// this is the 1st dirent bh
|
||||||
nlink_t old_dir_nlink = old_dir->i_nlink;
|
nlink_t old_dir_nlink = old_dir->i_nlink;
|
||||||
|
struct ocfs2_dinode *old_di;
|
||||||
|
|
||||||
/* At some point it might be nice to break this function up a
|
/* At some point it might be nice to break this function up a
|
||||||
* bit. */
|
* bit. */
|
||||||
|
@ -1354,7 +1355,20 @@ static int ocfs2_rename(struct inode *old_dir,
|
||||||
|
|
||||||
old_inode->i_ctime = CURRENT_TIME;
|
old_inode->i_ctime = CURRENT_TIME;
|
||||||
mark_inode_dirty(old_inode);
|
mark_inode_dirty(old_inode);
|
||||||
ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh);
|
|
||||||
|
status = ocfs2_journal_access(handle, old_inode, old_inode_bh,
|
||||||
|
OCFS2_JOURNAL_ACCESS_WRITE);
|
||||||
|
if (status >= 0) {
|
||||||
|
old_di = (struct ocfs2_dinode *) old_inode_bh->b_data;
|
||||||
|
|
||||||
|
old_di->i_ctime = cpu_to_le64(old_inode->i_ctime.tv_sec);
|
||||||
|
old_di->i_ctime_nsec = cpu_to_le32(old_inode->i_ctime.tv_nsec);
|
||||||
|
|
||||||
|
status = ocfs2_journal_dirty(handle, old_inode_bh);
|
||||||
|
if (status < 0)
|
||||||
|
mlog_errno(status);
|
||||||
|
} else
|
||||||
|
mlog_errno(status);
|
||||||
|
|
||||||
/* now that the name has been added to new_dir, remove the old name */
|
/* now that the name has been added to new_dir, remove the old name */
|
||||||
status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
|
status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
|
||||||
|
|
|
@ -494,16 +494,16 @@ static inline unsigned int ocfs2_page_index_to_clusters(struct super_block *sb,
|
||||||
/*
|
/*
|
||||||
* Find the 1st page index which covers the given clusters.
|
* Find the 1st page index which covers the given clusters.
|
||||||
*/
|
*/
|
||||||
static inline unsigned long ocfs2_align_clusters_to_page_index(struct super_block *sb,
|
static inline pgoff_t ocfs2_align_clusters_to_page_index(struct super_block *sb,
|
||||||
u32 clusters)
|
u32 clusters)
|
||||||
{
|
{
|
||||||
unsigned int cbits = OCFS2_SB(sb)->s_clustersize_bits;
|
unsigned int cbits = OCFS2_SB(sb)->s_clustersize_bits;
|
||||||
unsigned long index = clusters;
|
pgoff_t index = clusters;
|
||||||
|
|
||||||
if (PAGE_CACHE_SHIFT > cbits) {
|
if (PAGE_CACHE_SHIFT > cbits) {
|
||||||
index = clusters >> (PAGE_CACHE_SHIFT - cbits);
|
index = (pgoff_t)clusters >> (PAGE_CACHE_SHIFT - cbits);
|
||||||
} else if (PAGE_CACHE_SHIFT < cbits) {
|
} else if (PAGE_CACHE_SHIFT < cbits) {
|
||||||
index = clusters << (cbits - PAGE_CACHE_SHIFT);
|
index = (pgoff_t)clusters << (cbits - PAGE_CACHE_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
|
|
@ -316,39 +316,51 @@ static void ocfs2_destroy_inode(struct inode *inode)
|
||||||
kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode));
|
kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* From xfs_super.c:xfs_max_file_offset
|
static unsigned long long ocfs2_max_file_offset(unsigned int bbits,
|
||||||
* Copyright (c) 2000-2004 Silicon Graphics, Inc.
|
unsigned int cbits)
|
||||||
*/
|
|
||||||
unsigned long long ocfs2_max_file_offset(unsigned int blockshift)
|
|
||||||
{
|
{
|
||||||
unsigned int pagefactor = 1;
|
unsigned int bytes = 1 << cbits;
|
||||||
unsigned int bitshift = BITS_PER_LONG - 1;
|
unsigned int trim = bytes;
|
||||||
|
unsigned int bitshift = 32;
|
||||||
|
|
||||||
/* Figure out maximum filesize, on Linux this can depend on
|
/*
|
||||||
* the filesystem blocksize (on 32 bit platforms).
|
* i_size and all block offsets in ocfs2 are always 64 bits
|
||||||
* __block_prepare_write does this in an [unsigned] long...
|
* wide. i_clusters is 32 bits, in cluster-sized units. So on
|
||||||
* page->index << (PAGE_CACHE_SHIFT - bbits)
|
* 64 bit platforms, cluster size will be the limiting factor.
|
||||||
* So, for page sized blocks (4K on 32 bit platforms),
|
|
||||||
* this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is
|
|
||||||
* (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
|
|
||||||
* but for smaller blocksizes it is less (bbits = log2 bsize).
|
|
||||||
* Note1: get_block_t takes a long (implicit cast from above)
|
|
||||||
* Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch
|
|
||||||
* can optionally convert the [unsigned] long from above into
|
|
||||||
* an [unsigned] long long.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if BITS_PER_LONG == 32
|
#if BITS_PER_LONG == 32
|
||||||
# if defined(CONFIG_LBD)
|
# if defined(CONFIG_LBD)
|
||||||
BUILD_BUG_ON(sizeof(sector_t) != 8);
|
BUILD_BUG_ON(sizeof(sector_t) != 8);
|
||||||
pagefactor = PAGE_CACHE_SIZE;
|
/*
|
||||||
bitshift = BITS_PER_LONG;
|
* We might be limited by page cache size.
|
||||||
|
*/
|
||||||
|
if (bytes > PAGE_CACHE_SIZE) {
|
||||||
|
bytes = PAGE_CACHE_SIZE;
|
||||||
|
trim = 1;
|
||||||
|
/*
|
||||||
|
* Shift by 31 here so that we don't get larger than
|
||||||
|
* MAX_LFS_FILESIZE
|
||||||
|
*/
|
||||||
|
bitshift = 31;
|
||||||
|
}
|
||||||
# else
|
# else
|
||||||
pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
|
/*
|
||||||
|
* We are limited by the size of sector_t. Use block size, as
|
||||||
|
* that's what we expose to the VFS.
|
||||||
|
*/
|
||||||
|
bytes = 1 << bbits;
|
||||||
|
trim = 1;
|
||||||
|
bitshift = 31;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (((unsigned long long)pagefactor) << bitshift) - 1;
|
/*
|
||||||
|
* Trim by a whole cluster when we can actually approach the
|
||||||
|
* on-disk limits. Otherwise we can overflow i_clusters when
|
||||||
|
* an extent start is at the max offset.
|
||||||
|
*/
|
||||||
|
return (((unsigned long long)bytes) << bitshift) - trim;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
|
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,
|
||||||
int sector_size)
|
int sector_size)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
int i;
|
int i, cbits, bbits;
|
||||||
struct ocfs2_dinode *di = NULL;
|
struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
struct buffer_head *bitmap_bh = NULL;
|
struct buffer_head *bitmap_bh = NULL;
|
||||||
struct ocfs2_journal *journal;
|
struct ocfs2_journal *journal;
|
||||||
|
@ -1279,9 +1291,12 @@ static int ocfs2_initialize_super(struct super_block *sb,
|
||||||
sb->s_fs_info = osb;
|
sb->s_fs_info = osb;
|
||||||
sb->s_op = &ocfs2_sops;
|
sb->s_op = &ocfs2_sops;
|
||||||
sb->s_export_op = &ocfs2_export_ops;
|
sb->s_export_op = &ocfs2_export_ops;
|
||||||
|
sb->s_time_gran = 1;
|
||||||
sb->s_flags |= MS_NOATIME;
|
sb->s_flags |= MS_NOATIME;
|
||||||
/* this is needed to support O_LARGEFILE */
|
/* this is needed to support O_LARGEFILE */
|
||||||
sb->s_maxbytes = ocfs2_max_file_offset(sb->s_blocksize_bits);
|
cbits = le32_to_cpu(di->id2.i_super.s_clustersize_bits);
|
||||||
|
bbits = le32_to_cpu(di->id2.i_super.s_blocksize_bits);
|
||||||
|
sb->s_maxbytes = ocfs2_max_file_offset(bbits, cbits);
|
||||||
|
|
||||||
osb->sb = sb;
|
osb->sb = sb;
|
||||||
/* Save off for ocfs2_rw_direct */
|
/* Save off for ocfs2_rw_direct */
|
||||||
|
@ -1341,8 +1356,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
|
||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
di = (struct ocfs2_dinode *)bh->b_data;
|
|
||||||
|
|
||||||
osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
|
osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
|
||||||
if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) {
|
if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) {
|
||||||
mlog(ML_ERROR, "Invalid number of node slots (%u)\n",
|
mlog(ML_ERROR, "Invalid number of node slots (%u)\n",
|
||||||
|
|
|
@ -45,6 +45,4 @@ void __ocfs2_abort(struct super_block *sb,
|
||||||
|
|
||||||
#define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args)
|
#define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args)
|
||||||
|
|
||||||
unsigned long long ocfs2_max_file_offset(unsigned int blockshift);
|
|
||||||
|
|
||||||
#endif /* OCFS2_SUPER_H */
|
#endif /* OCFS2_SUPER_H */
|
||||||
|
|
Loading…
Reference in New Issue