* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, 2016, Intel Corporation.
+ * Copyright (c) 2011, 2017, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
sbi->ll_ra_info.ra_max_pages_per_file = min(pages / 32,
SBI_DEFAULT_READAHEAD_MAX);
sbi->ll_ra_info.ra_max_pages = sbi->ll_ra_info.ra_max_pages_per_file;
- sbi->ll_ra_info.ra_max_read_ahead_whole_pages =
- SBI_DEFAULT_READAHEAD_WHOLE_MAX;
+ sbi->ll_ra_info.ra_max_read_ahead_whole_pages = -1;
ll_generate_random_uuid(uuid);
class_uuid_unparse(uuid, &sbi->ll_sb_uuid);
}
/* metadata statahead is enabled by default */
+ sbi->ll_sa_running_max = LL_SA_RUNNING_DEF;
sbi->ll_sa_max = LL_SA_RPC_DEF;
atomic_set(&sbi->ll_sa_total, 0);
atomic_set(&sbi->ll_sa_wrong, 0);
atomic_set(&sbi->ll_agl_total, 0);
sbi->ll_flags |= LL_SBI_AGL_ENABLED;
sbi->ll_flags |= LL_SBI_FAST_READ;
+ sbi->ll_flags |= LL_SBI_TINY_WRITE;
/* root squash */
sbi->ll_squash.rsi_uid = 0;
RETURN(-ENOMEM);
}
+ /* pass client page size via ocd_grant_blkbits, the server should report
+ * back its backend blocksize for grant calculation purpose */
+ data->ocd_grant_blkbits = PAGE_SHIFT;
+
/* indicate MDT features supported by this client */
data->ocd_connect_flags = OBD_CONNECT_IBITS | OBD_CONNECT_NODEVOH |
OBD_CONNECT_ATTRFID | OBD_CONNECT_GRANT |
OBD_CONNECT_DIR_STRIPE |
OBD_CONNECT_BULK_MBITS | OBD_CONNECT_CKSUM |
OBD_CONNECT_SUBTREE |
- OBD_CONNECT_FLAGS2 | OBD_CONNECT_MULTIMODRPCS;
+ OBD_CONNECT_MULTIMODRPCS |
+ OBD_CONNECT_GRANT_PARAM |
+ OBD_CONNECT_SHORTIO | OBD_CONNECT_FLAGS2;
- data->ocd_connect_flags2 = 0;
+ data->ocd_connect_flags2 = OBD_CONNECT2_FLR |
+ OBD_CONNECT2_LOCK_CONVERT |
+ OBD_CONNECT2_DIR_MIGRATE |
+ OBD_CONNECT2_SUM_STATFS;
#ifdef HAVE_LRU_RESIZE_SUPPORT
if (sbi->ll_flags & LL_SBI_LRU_RESIZE)
OBD_CONNECT_LARGE_ACL;
#endif
- data->ocd_cksum_types = cksum_types_supported_client();
+ data->ocd_cksum_types = obd_cksum_types_supported_client();
if (OBD_FAIL_CHECK(OBD_FAIL_MDC_LIGHTWEIGHT))
/* flag mdc connection as lightweight, only used for test
if (sbi->ll_flags & LL_SBI_ALWAYS_PING)
data->ocd_connect_flags &= ~OBD_CONNECT_PINGLESS;
-#ifdef HAVE_SECURITY_DENTRY_INIT_SECURITY
+#if defined(HAVE_SECURITY_DENTRY_INIT_SECURITY) && defined(CONFIG_SECURITY)
data->ocd_connect_flags2 |= OBD_CONNECT2_FILE_SECCTX;
#endif /* HAVE_SECURITY_DENTRY_INIT_SECURITY */
* can make sure the client can be mounted as long as MDT0 is
* avaible */
err = obd_statfs(NULL, sbi->ll_md_exp, osfs,
- cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
+ ktime_get_seconds() -OBD_STATFS_CACHE_SECONDS,
OBD_STATFS_FOR_MDT0);
if (err)
GOTO(out_md_fid, err);
OBD_CONNECT_JOBSTATS | OBD_CONNECT_LVB_TYPE |
OBD_CONNECT_LAYOUTLOCK |
OBD_CONNECT_PINGLESS | OBD_CONNECT_LFSCK |
- OBD_CONNECT_BULK_MBITS |
- OBD_CONNECT_FLAGS2;
+ OBD_CONNECT_BULK_MBITS | OBD_CONNECT_SHORTIO |
+ OBD_CONNECT_FLAGS2 | OBD_CONNECT_GRANT_SHRINK;
/* The client currently advertises support for OBD_CONNECT_LOCKAHEAD_OLD so it
* can interoperate with an older version of lockahead which was released prior
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();
+ data->ocd_cksum_types = obd_cksum_types_supported_client();
#ifdef HAVE_LRU_RESIZE_SUPPORT
data->ocd_connect_flags |= OBD_CONNECT_LRU_RESIZE;
sbi->ll_dt_exp->exp_connect_data = *data;
+ /* Don't change value if it was specified in the config log */
+ if (sbi->ll_ra_info.ra_max_read_ahead_whole_pages == -1)
+ sbi->ll_ra_info.ra_max_read_ahead_whole_pages =
+ max_t(unsigned long, SBI_DEFAULT_READAHEAD_WHOLE_MAX,
+ (data->ocd_brw_size >> PAGE_SHIFT));
+
err = obd_fid_init(sbi->ll_dt_exp->exp_obd, sbi->ll_dt_exp,
LUSTRE_SEQ_METADATA);
if (err) {
}
checksum = sbi->ll_flags & LL_SBI_CHECKSUM;
- err = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_CHECKSUM),
- KEY_CHECKSUM, sizeof(checksum), &checksum,
- NULL);
- if (err) {
- CERROR("%s: Set checksum failed: rc = %d\n",
- sbi->ll_dt_exp->exp_obd->obd_name, err);
- GOTO(out_root, err);
+ if (sbi->ll_checksum_set) {
+ err = obd_set_info_async(NULL, sbi->ll_dt_exp,
+ sizeof(KEY_CHECKSUM), KEY_CHECKSUM,
+ sizeof(checksum), &checksum, NULL);
+ if (err) {
+ CERROR("%s: Set checksum failed: rc = %d\n",
+ sbi->ll_dt_exp->exp_obd->obd_name, err);
+ GOTO(out_root, err);
+ }
}
cl_sb_init(sb);
obd_disconnect(sbi->ll_dt_exp);
sbi->ll_dt_exp = NULL;
- lprocfs_ll_unregister_mountpoint(sbi);
+ ll_debugfs_unregister_super(sb);
obd_fid_fini(sbi->ll_md_exp->exp_obd);
obd_disconnect(sbi->ll_md_exp);
static inline int ll_set_opt(const char *opt, char *data, int fl)
{
- if (strncmp(opt, data, strlen(opt)) != 0)
- return(0);
- else
- return(fl);
+ if (strncmp(opt, data, strlen(opt)) != 0)
+ return 0;
+ else
+ return fl;
}
/* non-client-specific mount options are parsed in lmd_parse */
-static int ll_options(char *options, int *flags)
+static int ll_options(char *options, struct ll_sb_info *sbi)
{
- int tmp;
- char *s1 = options, *s2;
- ENTRY;
+ int tmp;
+ char *s1 = options, *s2;
+ int *flags = &sbi->ll_flags;
+ ENTRY;
- if (!options)
- RETURN(0);
+ if (!options)
+ RETURN(0);
- CDEBUG(D_CONFIG, "Parsing opts %s\n", options);
+ CDEBUG(D_CONFIG, "Parsing opts %s\n", options);
while (*s1) {
CDEBUG(D_SUPER, "next opt=%s\n", s1);
goto next;
}
- tmp = ll_set_opt("checksum", s1, LL_SBI_CHECKSUM);
- if (tmp) {
- *flags |= tmp;
- goto next;
- }
- tmp = ll_set_opt("nochecksum", s1, LL_SBI_CHECKSUM);
- if (tmp) {
- *flags &= ~tmp;
- goto next;
- }
+ tmp = ll_set_opt("checksum", s1, LL_SBI_CHECKSUM);
+ if (tmp) {
+ *flags |= tmp;
+ sbi->ll_checksum_set = 1;
+ goto next;
+ }
+ tmp = ll_set_opt("nochecksum", s1, LL_SBI_CHECKSUM);
+ if (tmp) {
+ *flags &= ~tmp;
+ sbi->ll_checksum_set = 1;
+ goto next;
+ }
tmp = ll_set_opt("lruresize", s1, LL_SBI_LRU_RESIZE);
if (tmp) {
*flags |= tmp;
init_rwsem(&lli->lli_trunc_sem);
range_lock_tree_init(&lli->lli_write_tree);
init_rwsem(&lli->lli_glimpse_sem);
- lli->lli_glimpse_time = 0;
+ lli->lli_glimpse_time = ktime_set(0, 0);
INIT_LIST_HEAD(&lli->lli_agl_list);
lli->lli_agl_index = 0;
lli->lli_async_rc = 0;
}
mutex_init(&lli->lli_layout_mutex);
- memset(lli->lli_jobid, 0, LUSTRE_JOBID_SIZE);
+ memset(lli->lli_jobid, 0, sizeof(lli->lli_jobid));
}
-static inline int ll_bdi_register(struct backing_dev_info *bdi)
+#define MAX_STRING_SIZE 128
+
+#ifndef HAVE_SUPER_SETUP_BDI_NAME
+
+#define LSI_BDI_INITIALIZED 0x00400000
+
+#ifndef HAVE_BDI_CAP_MAP_COPY
+# define BDI_CAP_MAP_COPY 0
+#endif
+
+static int super_setup_bdi_name(struct super_block *sb, char *fmt, ...)
{
- static atomic_t ll_bdi_num = ATOMIC_INIT(0);
+ struct lustre_sb_info *lsi = s2lsi(sb);
+ char buf[MAX_STRING_SIZE];
+ va_list args;
+ int err;
+
+ err = bdi_init(&lsi->lsi_bdi);
+ if (err)
+ return err;
+
+ lsi->lsi_flags |= LSI_BDI_INITIALIZED;
+ lsi->lsi_bdi.capabilities = BDI_CAP_MAP_COPY;
+ lsi->lsi_bdi.name = "lustre";
+ va_start(args, fmt);
+ vsnprintf(buf, MAX_STRING_SIZE, fmt, args);
+ va_end(args);
+ err = bdi_register(&lsi->lsi_bdi, NULL, "%s", buf);
+ va_end(args);
+ if (!err)
+ sb->s_bdi = &lsi->lsi_bdi;
- bdi->name = "lustre";
- return bdi_register(bdi, NULL, "lustre-%d",
- atomic_inc_return(&ll_bdi_num));
+ return err;
}
+#endif /* !HAVE_SUPER_SETUP_BDI_NAME */
int ll_fill_super(struct super_block *sb, struct vfsmount *mnt)
{
struct lustre_profile *lprof = NULL;
struct lustre_sb_info *lsi = s2lsi(sb);
- struct ll_sb_info *sbi;
+ struct ll_sb_info *sbi = NULL;
char *dt = NULL, *md = NULL;
char *profilenm = get_profile_name(sb);
struct config_llog_instance *cfg;
/* %p for void* in printf needs 16+2 characters: 0xffffffffffffffff */
const int instlen = sizeof(cfg->cfg_instance) * 2 + 2;
- int md_len = 0;
- int dt_len = 0;
- int err;
- ENTRY;
+ char name[MAX_STRING_SIZE];
+ int md_len = 0;
+ int dt_len = 0;
+ char *ptr;
+ int len;
+ int err;
+ ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb);
+ try_module_get(THIS_MODULE);
+
OBD_ALLOC_PTR(cfg);
if (cfg == NULL)
- RETURN(-ENOMEM);
-
- try_module_get(THIS_MODULE);
+ GOTO(out_free, err = -ENOMEM);
/* client additional sb info */
lsi->lsi_llsbi = sbi = ll_init_sbi();
- if (!sbi) {
- module_put(THIS_MODULE);
- OBD_FREE_PTR(cfg);
- RETURN(-ENOMEM);
- }
+ if (!sbi)
+ GOTO(out_free, err = -ENOMEM);
- err = ll_options(lsi->lsi_lmd->lmd_opts, &sbi->ll_flags);
+ err = ll_options(lsi->lsi_lmd->lmd_opts, sbi);
if (err)
GOTO(out_free, err);
- err = bdi_init(&lsi->lsi_bdi);
- if (err)
- GOTO(out_free, err);
- lsi->lsi_flags |= LSI_BDI_INITIALIZED;
-#ifdef HAVE_BDI_CAP_MAP_COPY
- lsi->lsi_bdi.capabilities = BDI_CAP_MAP_COPY;
-#else
- lsi->lsi_bdi.capabilities = 0;
-#endif
- err = ll_bdi_register(&lsi->lsi_bdi);
+ err = super_setup_bdi_name(sb, "lustre-%p", sb);
if (err)
GOTO(out_free, err);
- sb->s_bdi = &lsi->lsi_bdi;
#ifndef HAVE_DCACHE_LOCK
/* kernel >= 2.6.38 store dentry operations in sb->s_d_op. */
sb->s_d_op = &ll_d_ops;
#endif
+ /* Get fsname */
+ len = strlen(lsi->lsi_lmd->lmd_profile);
+ ptr = strrchr(lsi->lsi_lmd->lmd_profile, '-');
+ if (ptr && (strcmp(ptr, "-client") == 0))
+ len -= 7;
- /* Call lprocfs_ll_register_mountpoint() before lustre_process_log()
- * so that "llite.*.*" params can be processed correctly. */
- if (proc_lustre_fs_root != NULL) {
- err = lprocfs_ll_register_mountpoint(proc_lustre_fs_root, sb);
- if (err < 0) {
- CERROR("%s: could not register mountpoint in llite: "
- "rc = %d\n", ll_get_fsname(sb, NULL, 0), err);
- err = 0;
- }
+ /* Mount info */
+ snprintf(name, MAX_STRING_SIZE, "%.*s-%p", len,
+ lsi->lsi_lmd->lmd_profile, sb);
+
+ /* Call ll_debugfs_register_super() before lustre_process_log()
+ * so that "llite.*.*" params can be processed correctly.
+ */
+ err = ll_debugfs_register_super(sb, name);
+ if (err < 0) {
+ CERROR("%s: could not register mountpoint in llite: rc = %d\n",
+ ll_get_fsname(sb, NULL, 0), err);
+ err = 0;
}
/* Generate a string unique to this super, in case some joker tries
out_proc:
if (err < 0)
- lprocfs_ll_unregister_mountpoint(sbi);
+ ll_debugfs_unregister_super(sb);
out_free:
if (md)
OBD_FREE(md, md_len);
OBD_FREE(dt, dt_len);
if (lprof != NULL)
class_put_profile(lprof);
+ if (cfg)
+ OBD_FREE_PTR(cfg);
if (err)
ll_put_super(sb);
else if (sbi->ll_flags & LL_SBI_VERBOSE)
LCONSOLE_WARN("Mounted %s\n", profilenm);
-
- OBD_FREE_PTR(cfg);
RETURN(err);
} /* ll_fill_super */
int next, force = 1, rc = 0;
ENTRY;
+ if (!sbi)
+ GOTO(out_no_sbi, 0);
+
CDEBUG(D_VFSTRACE, "VFS Op: sb %p - %s\n", sb, profilenm);
cfg.cfg_instance = sb;
if (profilenm)
class_del_profile(profilenm);
+#ifndef HAVE_SUPER_SETUP_BDI_NAME
if (lsi->lsi_flags & LSI_BDI_INITIALIZED) {
bdi_destroy(&lsi->lsi_bdi);
lsi->lsi_flags &= ~LSI_BDI_INITIALIZED;
}
+#endif
ll_free_sbi(sb);
lsi->lsi_llsbi = NULL;
-
+out_no_sbi:
lustre_common_put_super(sb);
cl_env_cache_purge(~0);
return ll_setattr_raw(de, attr, false);
}
-int ll_statfs_internal(struct super_block *sb, struct obd_statfs *osfs,
- __u64 max_age, __u32 flags)
+int ll_statfs_internal(struct ll_sb_info *sbi, struct obd_statfs *osfs,
+ u32 flags)
{
- struct ll_sb_info *sbi = ll_s2sbi(sb);
- struct obd_statfs obd_osfs;
- int rc;
- ENTRY;
+ struct obd_statfs obd_osfs;
+ time64_t max_age;
+ int rc;
+
+ ENTRY;
+ max_age = ktime_get_seconds() - OBD_STATFS_CACHE_SECONDS;
rc = obd_statfs(NULL, sbi->ll_md_exp, osfs, max_age, flags);
if (rc) {
RETURN(rc);
}
- osfs->os_type = sb->s_magic;
+ osfs->os_type = LL_SUPER_MAGIC;
CDEBUG(D_SUPER, "MDC blocks %llu/%llu objects %llu/%llu\n",
osfs->os_bavail, osfs->os_blocks, osfs->os_ffree,osfs->os_files);
+ if (osfs->os_state & OS_STATE_SUM)
+ GOTO(out, rc);
+
if (sbi->ll_flags & LL_SBI_LAZYSTATFS)
flags |= OBD_STATFS_NODELAY;
- rc = obd_statfs_rqset(sbi->ll_dt_exp, &obd_osfs, max_age, flags);
+ rc = obd_statfs(NULL, sbi->ll_dt_exp, &obd_osfs, max_age, flags);
if (rc) {
CERROR("obd_statfs fails: rc = %d\n", rc);
RETURN(rc);
osfs->os_ffree = obd_osfs.os_ffree;
}
+out:
RETURN(rc);
}
int ll_statfs(struct dentry *de, struct kstatfs *sfs)
CDEBUG(D_VFSTRACE, "VFS Op: at %llu jiffies\n", get_jiffies_64());
ll_stats_ops_tally(ll_s2sbi(sb), LPROC_LL_STAFS, 1);
- /* Some amount of caching on the client is allowed */
- rc = ll_statfs_internal(sb, &osfs,
- cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
- 0);
- if (rc)
- return rc;
+ /* Some amount of caching on the client is allowed */
+ rc = ll_statfs_internal(ll_s2sbi(sb), &osfs, OBD_STATFS_SUM);
+ if (rc)
+ return rc;
statfs_unpack(sfs, &osfs);
mutex_unlock(&lli->lli_size_mutex);
}
+void ll_update_inode_flags(struct inode *inode, int ext_flags)
+{
+ inode->i_flags = ll_ext_to_inode_flags(ext_flags);
+ if (ext_flags & LUSTRE_PROJINHERIT_FL)
+ ll_file_set_flag(ll_i2info(inode), LLIF_PROJECT_INHERIT);
+ else
+ ll_file_clear_flag(ll_i2info(inode), LLIF_PROJECT_INHERIT);
+}
+
int ll_update_inode(struct inode *inode, struct lustre_md *md)
{
struct ll_inode_info *lli = ll_i2info(inode);
/* Clear i_flags to remove S_NOSEC before permissions are updated */
if (body->mbo_valid & OBD_MD_FLFLAGS)
- inode->i_flags = ll_ext_to_inode_flags(body->mbo_flags);
+ ll_update_inode_flags(inode, body->mbo_flags);
if (body->mbo_valid & OBD_MD_FLMODE)
inode->i_mode = (inode->i_mode & S_IFMT) |
(body->mbo_mode & ~S_IFMT);
truncate_inode_pages_final(&inode->i_data);
LASSERTF(inode->i_data.nrpages == 0, "inode="DFID"(%p) nrpages=%lu, "
- "see https://jira.hpdd.intel.com/browse/LU-118\n",
+ "see https://jira.whamcloud.com/browse/LU-118\n",
PFID(ll_inode2fid(inode)), inode, inode->i_data.nrpages);
#ifdef HAVE_SBOPS_EVICT_INODE
int ll_iocontrol(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct ptlrpc_request *req = NULL;
- int rc, flags = 0;
- ENTRY;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct ptlrpc_request *req = NULL;
+ int rc, flags = 0;
+ ENTRY;
- switch(cmd) {
- case FSFILT_IOC_GETFLAGS: {
+ switch (cmd) {
+ case FS_IOC_GETFLAGS: {
struct mdt_body *body;
struct md_op_data *op_data;
flags = body->mbo_flags;
- ptlrpc_req_finished(req);
+ ptlrpc_req_finished(req);
RETURN(put_user(flags, (int __user *)arg));
- }
- case FSFILT_IOC_SETFLAGS: {
+ }
+ case FS_IOC_SETFLAGS: {
struct iattr *attr;
struct md_op_data *op_data;
struct cl_object *obj;
if (rc)
RETURN(rc);
- inode->i_flags = ll_ext_to_inode_flags(flags);
+ ll_update_inode_flags(inode, flags);
obj = ll_i2info(inode)->lli_clob;
if (obj == NULL)
return rc;
}
-int ll_process_config(struct lustre_cfg *lcfg)
-{
- struct super_block *sb;
- unsigned long x;
- int rc = 0;
- char *ptr;
-
- /* The instance name contains the sb: lustre-client-aacfe000 */
- ptr = strrchr(lustre_cfg_string(lcfg, 0), '-');
- if (!ptr || !*(++ptr))
- return -EINVAL;
- if (sscanf(ptr, "%lx", &x) != 1)
- return -EINVAL;
- sb = (struct super_block *)x;
- /* This better be a real Lustre superblock! */
- LASSERT(s2lsi(sb)->lsi_lmd->lmd_magic == LMD_MAGIC);
-
- /* Note we have not called client_common_fill_super yet, so
- proc fns must be able to handle that! */
- rc = class_process_proc_param(PARAM_LLITE, lprocfs_llite_obd_vars,
- lcfg, sb);
- if (rc > 0)
- rc = 0;
- return rc;
-}
-
/* this function prepares md_op_data hint for passing it down to MD stack. */
struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
struct inode *i1, struct inode *i2,
op_data->op_name = name;
op_data->op_namelen = namelen;
op_data->op_mode = mode;
- op_data->op_mod_time = cfs_time_current_sec();
+ op_data->op_mod_time = ktime_get_real_seconds();
op_data->op_fsuid = from_kuid(&init_user_ns, current_fsuid());
op_data->op_fsgid = from_kgid(&init_user_ns, current_fsgid());
op_data->op_cap = cfs_curproc_cap_pack();
+ op_data->op_mds = 0;
if ((opc == LUSTRE_OPC_CREATE) && (name != NULL) &&
filename_is_volatile(name, namelen, &op_data->op_mds)) {
op_data->op_bias |= MDS_CREATE_VOLATILE;
- } else {
- op_data->op_mds = 0;
}
op_data->op_data = data;