Add a call to inode_newsize_ok() in ll_setattr_raw() to ensure
that the file is not truncated beyond the VFS/VM maximum limits
or the user maximum file size, as set by rlimit.
Replace the PAGE_CACHE_MAXBYTES constant with MAX_LFS_FILESIZE,
which is already defined by the VFS.
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Change-Id: I6b4f03820dd59d6b1c3429e9bbfea62c50206cc9
Reviewed-on: http://review.whamcloud.com/1635
Reviewed-by: Jinshan Xiong <jinshan.xiong@whamcloud.com>
Tested-by: Hudson
Reviewed-by: Bobi Jam <bobijam@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
#include <lustre_mds.h>
#include <lustre_ha.h>
#include <lustre_mds.h>
#include <lustre_ha.h>
-#ifdef __KERNEL__
-
-/* careful, this is easy to screw up */
-#define PAGE_CACHE_MAXBYTES ((__u64)(~0UL) << CFS_PAGE_SHIFT)
-
-#endif
-
/* 4UL * 1024 * 1024 */
#define LL_MAX_BLKSIZE_BITS (22)
#define LL_MAX_BLKSIZE (1UL<<LL_MAX_BLKSIZE_BITS)
/* 4UL * 1024 * 1024 */
#define LL_MAX_BLKSIZE_BITS (22)
#define LL_MAX_BLKSIZE (1UL<<LL_MAX_BLKSIZE_BITS)
/* This should not be "optimized" use ~0ULL because page->index is a long and
* 32-bit systems are therefore limited to 16TB in a mapping */
/* This should not be "optimized" use ~0ULL because page->index is a long and
* 32-bit systems are therefore limited to 16TB in a mapping */
-#define PAGE_CACHE_MAXBYTES ((__u64)(~0UL) << CFS_PAGE_SHIFT)
+#define MAX_LFS_FILESIZE ((__u64)(~0UL) << CFS_PAGE_SHIFT)
struct ll_file_data {
struct obd_client_handle fd_mds_och;
__u32 fd_flags;
struct ll_file_data {
struct obd_client_handle fd_mds_och;
__u32 fd_flags;
cl_file_inode_init(inode, md);
lli->lli_smd = lsm;
lli->lli_maxbytes = lsm->lsm_maxbytes;
cl_file_inode_init(inode, md);
lli->lli_smd = lsm;
lli->lli_maxbytes = lsm->lsm_maxbytes;
- if (lli->lli_maxbytes > PAGE_CACHE_MAXBYTES)
- lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
+ if (lli->lli_maxbytes > MAX_LFS_FILESIZE)
+ lli->lli_maxbytes = MAX_LFS_FILESIZE;
} else {
if (lov_stripe_md_cmp(lli->lli_smd, lsm)) {
CERROR("lsm mismatch for inode %lld\n",
} else {
if (lov_stripe_md_cmp(lli->lli_smd, lsm)) {
CERROR("lsm mismatch for inode %lld\n",
sb->s_blocksize = osfs->os_bsize;
sb->s_blocksize_bits = log2(osfs->os_bsize);
sb->s_magic = LL_SUPER_MAGIC;
sb->s_blocksize = osfs->os_bsize;
sb->s_blocksize_bits = log2(osfs->os_bsize);
sb->s_magic = LL_SUPER_MAGIC;
-
- /* for bug 11559. in $LINUX/fs/read_write.c, function do_sendfile():
- * retval = in_file->f_op->sendfile(...);
- * if (*ppos > max)
- * retval = -EOVERFLOW;
- *
- * it will check if *ppos is greater than max. However, max equals to
- * s_maxbytes, which is a negative integer in a x86_64 box since loff_t
- * has been defined as a signed long long integer in linux kernel. */
-#if BITS_PER_LONG == 64
- sb->s_maxbytes = PAGE_CACHE_MAXBYTES >> 1;
-#else
- sb->s_maxbytes = PAGE_CACHE_MAXBYTES;
-#endif
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
sbi->ll_namelen = osfs->os_namelen;
sbi->ll_max_rw_chunk = LL_DEFAULT_MAX_RW_CHUNK;
sbi->ll_namelen = osfs->os_namelen;
sbi->ll_max_rw_chunk = LL_DEFAULT_MAX_RW_CHUNK;
lli->lli_inode_magic = LLI_INODE_MAGIC;
lli->lli_flags = 0;
lli->lli_ioepoch = 0;
lli->lli_inode_magic = LLI_INODE_MAGIC;
lli->lli_flags = 0;
lli->lli_ioepoch = 0;
+ lli->lli_maxbytes = MAX_LFS_FILESIZE;
cfs_spin_lock_init(&lli->lli_lock);
lli->lli_posix_acl = NULL;
lli->lli_remote_perms = NULL;
cfs_spin_lock_init(&lli->lli_lock);
lli->lli_posix_acl = NULL;
lli->lli_remote_perms = NULL;
cfs_sema_init(&lli->lli_size_sem, 1);
lli->lli_size_sem_owner = NULL;
lli->lli_symlink_name = NULL;
cfs_sema_init(&lli->lli_size_sem, 1);
lli->lli_size_sem_owner = NULL;
lli->lli_symlink_name = NULL;
- lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
cfs_init_rwsem(&lli->lli_trunc_sem);
cfs_mutex_init(&lli->lli_write_mutex);
lli->lli_async_rc = 0;
cfs_init_rwsem(&lli->lli_trunc_sem);
cfs_mutex_init(&lli->lli_write_mutex);
lli->lli_async_rc = 0;
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETATTR, 1);
if (ia_valid & ATTR_SIZE) {
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETATTR, 1);
if (ia_valid & ATTR_SIZE) {
+ /* Check new size against VFS/VM file size limit and rlimit */
+ rc = inode_newsize_ok(inode, attr->ia_size);
+ if (rc)
+ RETURN(rc);
+
+ /* The maximum Lustre file size is variable, based on the
+ * OST maximum object size and number of stripes. This
+ * needs another check in addition to the VFS check above. */
if (attr->ia_size > ll_file_maxbytes(inode)) {
if (attr->ia_size > ll_file_maxbytes(inode)) {
- CDEBUG(D_INODE, "file too large %llu > "LPU64"\n",
- attr->ia_size, ll_file_maxbytes(inode));
+ CDEBUG(D_INODE,"file "DFID" too large %llu > "LPU64"\n",
+ PFID(&lli->lli_fid), attr->ia_size,
+ ll_file_maxbytes(inode));
if (ia_valid & (ATTR_SIZE |
ATTR_ATIME | ATTR_ATIME_SET |
ATTR_MTIME | ATTR_MTIME_SET))
if (ia_valid & (ATTR_SIZE |
ATTR_ATIME | ATTR_ATIME_SET |
ATTR_MTIME | ATTR_MTIME_SET))
- /* on truncate and utimes send attributes to osts, setting
- * mtime/atime to past will be performed under PW 0:EOF extent
- * lock (new_size:EOF for truncate)
- * it may seem excessive to send mtime/atime updates to osts
- * when not setting times to past, but it is necessary due to
- * possible time de-synchronization */
+ /* For truncate and utimes sending attributes to OSTs, setting
+ * mtime/atime to the past will be performed under PW [0:EOF]
+ * extent lock (new_size:EOF for truncate). It may seem
+ * excessive to send mtime/atime updates to OSTs when not
+ * setting times to past, but it is necessary due to possible
+ * time de-synchronization between MDT inode and OST objects */
rc = ll_setattr_ost(inode, attr);
EXIT;
out:
rc = ll_setattr_ost(inode, attr);
EXIT;
out:
cfs_spin_unlock(&lli->lli_lock);
cfs_mutex_unlock(&lli->lli_och_mutex);
lli->lli_maxbytes = lsm->lsm_maxbytes;
cfs_spin_unlock(&lli->lli_lock);
cfs_mutex_unlock(&lli->lli_och_mutex);
lli->lli_maxbytes = lsm->lsm_maxbytes;
- if (lli->lli_maxbytes > PAGE_CACHE_MAXBYTES)
- lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
+ if (lli->lli_maxbytes > MAX_LFS_FILESIZE)
+ lli->lli_maxbytes = MAX_LFS_FILESIZE;
} else {
cfs_mutex_unlock(&lli->lli_och_mutex);
LASSERT(lli->lli_smd->lsm_magic == lsm->lsm_magic &&
} else {
cfs_mutex_unlock(&lli->lli_och_mutex);
LASSERT(lli->lli_smd->lsm_magic == lsm->lsm_magic &&
sb->s_blocksize = 4096;
sb->s_blocksize_bits = log2(sb->s_blocksize);
sb->s_magic = LUSTRE_SUPER_MAGIC;
sb->s_blocksize = 4096;
sb->s_blocksize_bits = log2(sb->s_blocksize);
sb->s_magic = LUSTRE_SUPER_MAGIC;
- sb->s_maxbytes = 0; //PAGE_CACHE_MAXBYTES;
+ sb->s_maxbytes = 0; /* we don't allow file IO on server mountpoints */
sb->s_flags |= MS_RDONLY;
sb->s_op = &server_ops;
sb->s_flags |= MS_RDONLY;
sb->s_op = &server_ops;