-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
* GPL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
- */
-/*
- * Copyright (c) 2011 Whamcloud, Inc.
+ *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
RETURN(NULL);
cfs_spin_lock_init(&sbi->ll_lock);
- cfs_init_mutex(&sbi->ll_lco.lco_lock);
+ cfs_mutex_init(&sbi->ll_lco.lco_lock);
cfs_spin_lock_init(&sbi->ll_pp_extent_lock);
cfs_spin_lock_init(&sbi->ll_process_lock);
sbi->ll_rw_stats_on = 0;
cfs_list_add_tail(&sbi->ll_list, &ll_super_blocks);
cfs_spin_unlock(&ll_sb_lock);
+ sbi->ll_flags |= LL_SBI_VERBOSE;
#ifdef ENABLE_CHECKSUM
sbi->ll_flags |= LL_SBI_CHECKSUM;
#endif
OBD_CONNECT_CANCELSET | OBD_CONNECT_FID |
OBD_CONNECT_AT | OBD_CONNECT_LOV_V3 |
OBD_CONNECT_RMT_CLIENT | OBD_CONNECT_VBR |
- OBD_CONNECT_FULL20 | OBD_CONNECT_64BITHASH;
+ OBD_CONNECT_FULL20 | OBD_CONNECT_64BITHASH|
+ OBD_CONNECT_EINPROGRESS |
+ OBD_CONNECT_JOBSTATS;
if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
data->ocd_connect_flags |= OBD_CONNECT_SOM;
GOTO(out_md, err);
}
- err = obd_statfs(obd, osfs,
+ err = obd_statfs(NULL, sbi->ll_md_exp, osfs,
cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), 0);
if (err)
GOTO(out_md_fid, err);
}
size = sizeof(*data);
- err = obd_get_info(sbi->ll_md_exp, sizeof(KEY_CONN_DATA),
+ err = obd_get_info(NULL, sbi->ll_md_exp, sizeof(KEY_CONN_DATA),
KEY_CONN_DATA, &size, data, NULL);
if (err) {
CERROR("Get connect data failed: %d \n", err);
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;
OBD_CONNECT_AT | OBD_CONNECT_RMT_CLIENT |
OBD_CONNECT_OSS_CAPA | OBD_CONNECT_VBR|
OBD_CONNECT_FULL20 | OBD_CONNECT_64BITHASH |
- OBD_CONNECT_MAXBYTES;
+ OBD_CONNECT_MAXBYTES |
+ OBD_CONNECT_EINPROGRESS |
+ OBD_CONNECT_JOBSTATS;
if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
data->ocd_connect_flags |= OBD_CONNECT_SOM;
* agreement on the supported algorithms at connect time */
data->ocd_connect_flags |= OBD_CONNECT_CKSUM;
- if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CKSUM_ADLER_ONLY))
- data->ocd_cksum_types = OBD_CKSUM_ADLER;
- else
- data->ocd_cksum_types = cksum_types_supported();
+ if (OBD_FAIL_CHECK(OBD_FAIL_OSC_CKSUM_ADLER_ONLY))
+ data->ocd_cksum_types = OBD_CKSUM_ADLER;
+ else
+ data->ocd_cksum_types = cksum_types_supported_client();
}
#ifdef HAVE_LRU_RESIZE_SUPPORT
GOTO(out_dt, err);
}
- cfs_mutex_down(&sbi->ll_lco.lco_lock);
+ cfs_mutex_lock(&sbi->ll_lco.lco_lock);
sbi->ll_lco.lco_flags = data->ocd_connect_flags;
sbi->ll_lco.lco_md_exp = sbi->ll_md_exp;
sbi->ll_lco.lco_dt_exp = sbi->ll_dt_exp;
- cfs_mutex_up(&sbi->ll_lco.lco_lock);
+ cfs_mutex_unlock(&sbi->ll_lco.lco_lock);
fid_zero(&sbi->ll_root_fid);
err = md_getstatus(sbi->ll_md_exp, &sbi->ll_root_fid, &oc);
#endif
checksum = sbi->ll_flags & LL_SBI_CHECKSUM;
- err = obd_set_info_async(sbi->ll_dt_exp, sizeof(KEY_CHECKSUM),
+ err = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CHECKSUM),
KEY_CHECKSUM, sizeof(checksum), &checksum,
NULL);
cl_sb_init(sb);
*lmmsize = obd_size_diskmd(sbi->ll_dt_exp, NULL);
size = sizeof(int);
- rc = obd_get_info(sbi->ll_md_exp, sizeof(KEY_MAX_EASIZE),
+ rc = obd_get_info(NULL, sbi->ll_md_exp, sizeof(KEY_MAX_EASIZE),
KEY_MAX_EASIZE, &size, lmmsize, NULL);
if (rc)
CERROR("Get max mdsize error rc %d \n", rc);
*flags |= tmp;
goto next;
}
-
+ tmp = ll_set_opt("verbose", s1, LL_SBI_VERBOSE);
+ if (tmp) {
+ *flags |= tmp;
+ goto next;
+ }
+ tmp = ll_set_opt("noverbose", s1, LL_SBI_VERBOSE);
+ if (tmp) {
+ *flags &= ~tmp;
+ goto next;
+ }
LCONSOLE_ERROR_MSG(0x152, "Unknown option '%s', won't mount.\n",
s1);
RETURN(-EINVAL);
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_sema_init(&lli->lli_rmtperm_sem, 1);
+ cfs_mutex_init(&lli->lli_rmtperm_mutex);
/* Do not set lli_fid, it has been initialized already. */
fid_zero(&lli->lli_pfid);
CFS_INIT_LIST_HEAD(&lli->lli_close_list);
lli->lli_open_fd_read_count = 0;
lli->lli_open_fd_write_count = 0;
lli->lli_open_fd_exec_count = 0;
- cfs_sema_init(&lli->lli_och_sem, 1);
+ cfs_mutex_init(&lli->lli_och_mutex);
cfs_spin_lock_init(&lli->lli_agl_lock);
lli->lli_smd = NULL;
lli->lli_clob = NULL;
LASSERT(lli->lli_vfs_inode.i_mode != 0);
if (S_ISDIR(lli->lli_vfs_inode.i_mode)) {
- cfs_sema_init(&lli->lli_readdir_sem, 1);
+ cfs_mutex_init(&lli->lli_readdir_mutex);
lli->lli_opendir_key = NULL;
lli->lli_sai = NULL;
lli->lli_sa_pos = 0;
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_sema_init(&lli->lli_write_sem, 1);
+ cfs_mutex_init(&lli->lli_write_mutex);
lli->lli_async_rc = 0;
lli->lli_write_rc = 0;
cfs_init_rwsem(&lli->lli_glimpse_sem);
OBD_FREE(dt, strlen(lprof->lp_dt) + instlen + 2);
if (err)
ll_put_super(sb);
- else
- LCONSOLE_WARN("Client %s has started\n", profilenm);
+ else if (sbi->ll_flags & LL_SBI_VERBOSE)
+ LCONSOLE_WARN("Mounted %s\n", profilenm);
OBD_FREE_PTR(cfg);
RETURN(err);
class_manual_cleanup(obd);
}
+ if (sbi->ll_flags & LL_SBI_VERBOSE)
+ LCONSOLE_WARN("Unmounted %s\n", profilenm ? profilenm : "");
+
if (profilenm)
class_del_profile(profilenm);
cl_env_cache_purge(~0);
- LCONSOLE_WARN("client %p umount complete\n", cfg.cfg_instance);
-
cfs_module_put(THIS_MODULE);
EXIT;
struct inode *inode = dentry->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ptlrpc_request *request = NULL;
- int rc;
+ int rc, ia_valid;
ENTRY;
op_data = ll_prep_md_op_data(op_data, inode, NULL, NULL, 0, 0,
/* Unlinked special device node? Or just a race?
* Pretend we done everything. */
if (!S_ISREG(inode->i_mode) &&
- !S_ISDIR(inode->i_mode))
+ !S_ISDIR(inode->i_mode)) {
+ ia_valid = op_data->op_attr.ia_valid;
+ op_data->op_attr.ia_valid &= ~TIMES_SET_FLAGS;
rc = simple_setattr(dentry, &op_data->op_attr);
+ op_data->op_attr.ia_valid = ia_valid;
+ }
} else if (rc != -EPERM && rc != -EACCES && rc != -ETXTBSY) {
CERROR("md_setattr fails: rc = %d\n", rc);
}
RETURN(rc);
}
- /* We call inode_setattr to adjust timestamps.
+ /* We want to adjust timestamps.
* If there is at least some data in file, we cleared ATTR_SIZE
- * above to avoid invoking vmtruncate, otherwise it is important
- * to call vmtruncate in inode_setattr to update inode->i_size
+ * to avoid update size, otherwise it is important to do.(SOM case)
* (bug 6196) */
+ ia_valid = op_data->op_attr.ia_valid;
+ /* Since we set ATTR_*_SET flags above, and already done permission
+ * check, So don't let inode_change_ok() check it again. */
+ op_data->op_attr.ia_valid &= ~TIMES_SET_FLAGS;
rc = simple_setattr(dentry, &op_data->op_attr);
+ op_data->op_attr.ia_valid = ia_valid;
/* Extract epoch data if obtained. */
op_data->op_handle = md.body->handle;
CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu valid %x\n", inode->i_ino,
attr->ia_valid);
- 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)) {
- 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));
RETURN(-EFBIG);
}
}
/* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */
- if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) {
+ if (ia_valid & TIMES_SET_FLAGS) {
if (cfs_curproc_fsuid() != inode->i_uid &&
!cfs_capable(CFS_CAP_FOWNER))
RETURN(-EPERM);
if (op_data == NULL)
RETURN(-ENOMEM);
- UNLOCK_INODE_MUTEX(inode);
- if (ia_valid & ATTR_SIZE)
- UP_WRITE_I_ALLOC_SEM(inode);
- if (!S_ISDIR(inode->i_mode))
+ if (!S_ISDIR(inode->i_mode)) {
+ if (ia_valid & ATTR_SIZE)
+ UP_WRITE_I_ALLOC_SEM(inode);
+ UNLOCK_INODE_MUTEX(inode);
cfs_down_write(&lli->lli_trunc_sem);
- LOCK_INODE_MUTEX(inode);
- if (ia_valid & ATTR_SIZE)
- DOWN_WRITE_I_ALLOC_SEM(inode);
+ LOCK_INODE_MUTEX(inode);
+ if (ia_valid & ATTR_SIZE)
+ DOWN_WRITE_I_ALLOC_SEM(inode);
+ }
memcpy(&op_data->op_attr, attr, sizeof(*attr));
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:
if (op_data) {
- if (op_data->op_ioepoch)
+ if (op_data->op_ioepoch) {
rc1 = ll_setattr_done_writing(inode, op_data, mod);
+ if (!rc)
+ rc = rc1;
+ }
ll_finish_md_op_data(op_data);
}
if (!S_ISDIR(inode->i_mode))
cfs_up_write(&lli->lli_trunc_sem);
- return rc ? rc : rc1;
+
+ ll_stats_ops_tally(ll_i2sbi(inode), (ia_valid & ATTR_SIZE) ?
+ LPROC_LL_TRUNC : LPROC_LL_SETATTR, 1);
+
+ return rc;
}
int ll_setattr(struct dentry *de, struct iattr *attr)
int rc;
ENTRY;
- rc = obd_statfs(class_exp2obd(sbi->ll_md_exp), osfs, max_age, flags);
+ rc = obd_statfs(NULL, sbi->ll_md_exp, osfs, max_age, flags);
if (rc) {
CERROR("md_statfs fails: rc = %d\n", rc);
RETURN(rc);
if (sbi->ll_flags & LL_SBI_LAZYSTATFS)
flags |= OBD_STATFS_NODELAY;
- rc = obd_statfs_rqset(class_exp2obd(sbi->ll_dt_exp),
- &obd_osfs, max_age, flags);
+ rc = obd_statfs_rqset(sbi->ll_dt_exp, &obd_osfs, max_age, flags);
if (rc) {
CERROR("obd_statfs fails: rc = %d\n", rc);
RETURN(rc);
if (lsm != NULL) {
LASSERT(S_ISREG(inode->i_mode));
- cfs_down(&lli->lli_och_sem);
+ cfs_mutex_lock(&lli->lli_och_mutex);
if (lli->lli_smd == NULL) {
if (lsm->lsm_magic != LOV_MAGIC_V1 &&
lsm->lsm_magic != LOV_MAGIC_V3) {
cfs_spin_lock(&lli->lli_lock);
lli->lli_smd = lsm;
cfs_spin_unlock(&lli->lli_lock);
- cfs_up(&lli->lli_och_sem);
+ 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_up(&lli->lli_och_sem);
+ cfs_mutex_unlock(&lli->lli_och_mutex);
LASSERT(lli->lli_smd->lsm_magic == lsm->lsm_magic &&
lli->lli_smd->lsm_stripe_count ==
lsm->lsm_stripe_count);
oinfo.oi_oa->o_valid = OBD_MD_FLID | OBD_MD_FLFLAGS |
OBD_MD_FLGROUP;
oinfo.oi_capa = ll_mdscapa_get(inode);
- obdo_from_inode(oinfo.oi_oa, inode,
- &ll_i2info(inode)->lli_fid, 0);
+ obdo_set_parent_fid(oinfo.oi_oa, &ll_i2info(inode)->lli_fid);
rc = obd_setattr_rqset(sbi->ll_dt_exp, &oinfo, NULL);
capa_put(oinfo.oi_capa);
OBDO_FREE(oinfo.oi_oa);
CDEBUG(D_SEC, "flush context for user %d\n", cfs_curproc_uid());
- obd_set_info_async(sbi->ll_md_exp,
+ obd_set_info_async(NULL, sbi->ll_md_exp,
sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
0, NULL, NULL);
- obd_set_info_async(sbi->ll_dt_exp,
+ obd_set_info_async(NULL, sbi->ll_dt_exp,
sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
0, NULL, NULL);
return 0;
int ll_remount_fs(struct super_block *sb, int *flags, char *data)
{
struct ll_sb_info *sbi = ll_s2sbi(sb);
+ char *profilenm = get_profile_name(sb);
int err;
__u32 read_only;
if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
read_only = *flags & MS_RDONLY;
- err = obd_set_info_async(sbi->ll_md_exp,
+ err = obd_set_info_async(NULL, sbi->ll_md_exp,
sizeof(KEY_READ_ONLY),
KEY_READ_ONLY, sizeof(read_only),
&read_only, NULL);
if (err) {
- CERROR("Failed to change the read-only flag during "
- "remount: %d\n", err);
+ LCONSOLE_WARN("Failed to remount %s %s (%d)\n",
+ profilenm, read_only ?
+ "read-only" : "read-write", err);
return err;
}
sb->s_flags |= MS_RDONLY;
else
sb->s_flags &= ~MS_RDONLY;
+
+ if (sbi->ll_flags & LL_SBI_VERBOSE)
+ LCONSOLE_WARN("Remounted %s %s\n", profilenm,
+ read_only ? "read-only" : "read-write");
}
return 0;
}
GOTO(out_statfs, rc = -EINVAL);
memcpy(&type, data->ioc_inlbuf1, sizeof(__u32));
- if (type == LL_STATFS_MDC)
+ if (type == LL_STATFS_LMV)
exp = sbi->ll_md_exp;
else if (type == LL_STATFS_LOV)
exp = sbi->ll_dt_exp;
RETURN(0);
}
+
+/**
+ * Get obd name by cmd, and copy out to user space
+ */
+int ll_get_obd_name(struct inode *inode, unsigned int cmd, unsigned long arg)
+{
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct obd_device *obd;
+ ENTRY;
+
+ if (cmd == OBD_IOC_GETDTNAME)
+ obd = class_exp2obd(sbi->ll_dt_exp);
+ else if (cmd == OBD_IOC_GETMDNAME)
+ obd = class_exp2obd(sbi->ll_md_exp);
+ else
+ RETURN(-EINVAL);
+
+ if (!obd)
+ RETURN(-ENOENT);
+
+ if (cfs_copy_to_user((void *)arg, obd->obd_name,
+ strlen(obd->obd_name) + 1))
+ RETURN(-EFAULT);
+
+ RETURN(0);
+}