#include <linux/mm.h>
#include <linux/user_namespace.h>
#include <linux/delay.h>
-#ifdef HAVE_UIDGID_HEADER
-# include <linux/uidgid.h>
-#endif
+#include <linux/uidgid.h>
#include <linux/security.h>
#include <uapi/linux/lustre/lustre_ioctl.h>
#define log2(n) ffz(~(n))
#endif
+/**
+ * If there is only one number of core visible to Lustre,
+ * async readahead will be disabled, to avoid massive over
+ * subscription, we use 1/2 of active cores as default max
+ * async readahead requests.
+ */
+static inline unsigned int ll_get_ra_async_max_active(void)
+{
+ return cfs_cpt_weight(cfs_cpt_tab, CFS_CPT_ANY) >> 1;
+}
+
static struct ll_sb_info *ll_init_sbi(void)
{
struct ll_sb_info *sbi = NULL;
GOTO(out_destroy_ra, rc = -ENOMEM);
sbi->ll_ra_info.ra_max_pages_per_file = min(pages / 32,
- SBI_DEFAULT_READAHEAD_MAX);
+ SBI_DEFAULT_READ_AHEAD_MAX);
sbi->ll_ra_info.ra_async_pages_per_file_threshold =
sbi->ll_ra_info.ra_max_pages_per_file;
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 = -1;
+ sbi->ll_ra_info.ra_async_max_active = ll_get_ra_async_max_active();
+ atomic_set(&sbi->ll_ra_info.ra_async_inflight, 0);
sbi->ll_flags |= LL_SBI_VERBOSE;
#ifdef ENABLE_CHECKSUM
EXIT;
}
-static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
- struct vfsmount *mnt)
+static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
{
struct inode *root = NULL;
struct ll_sb_info *sbi = ll_s2sbi(sb);
OBD_CONNECT2_INC_XID |
OBD_CONNECT2_LSOM |
OBD_CONNECT2_ASYNC_DISCARD |
- OBD_CONNECT2_PCC;
+ OBD_CONNECT2_PCC |
+ OBD_CONNECT2_CRUSH;
#ifdef HAVE_LRU_RESIZE_SUPPORT
if (sbi->ll_flags & LL_SBI_LRU_RESIZE)
OBD_CONNECT_PINGLESS | OBD_CONNECT_LFSCK |
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
- * to landing in master. This support will be dropped when 2.13 development
- * starts. At the point, we should not just drop the connect flag (below), we
- * should also remove the support in the code.
- *
- * Removing it means a few things:
- * 1. Remove this section here
- * 2. Remove CEF_NONBLOCK in ll_file_lockahead()
- * 3. Remove function exp_connect_lockahead_old
- * 4. Remove LDLM_FL_LOCKAHEAD_OLD_RESERVED in lustre_dlm_flags.h
- * */
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 12, 50, 0)
- data->ocd_connect_flags |= OBD_CONNECT_LOCKAHEAD_OLD;
-#endif
-
data->ocd_connect_flags2 = OBD_CONNECT2_LOCKAHEAD |
OBD_CONNECT2_INC_XID;
/* 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,
+ max_t(unsigned long, SBI_DEFAULT_READ_AHEAD_WHOLE_MAX,
(data->ocd_brw_size >> PAGE_SHIFT));
if (sbi->ll_ra_info.ra_max_read_ahead_whole_pages >
sbi->ll_ra_info.ra_max_pages_per_file)
sb->s_dev = sbi->ll_sdev_orig;
/* wait running statahead threads to quit */
- while (atomic_read(&sbi->ll_sa_running) > 0) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(cfs_time_seconds(1) >> 3);
- }
+ while (atomic_read(&sbi->ll_sa_running) > 0)
+ schedule_timeout_uninterruptible(
+ cfs_time_seconds(1) >> 3);
}
EXIT;
} else {
mutex_init(&lli->lli_size_mutex);
lli->lli_symlink_name = NULL;
- init_rwsem(&lli->lli_trunc_sem);
+ ll_trunc_sem_init(&lli->lli_trunc_sem);
range_lock_tree_init(&lli->lli_write_tree);
init_rwsem(&lli->lli_glimpse_sem);
lli->lli_glimpse_time = ktime_set(0, 0);
}
#endif /* !HAVE_SUPER_SETUP_BDI_NAME */
-int ll_fill_super(struct super_block *sb, struct vfsmount *mnt)
+int ll_fill_super(struct super_block *sb)
{
struct lustre_profile *lprof = NULL;
struct lustre_sb_info *lsi = s2lsi(sb);
char *profilenm = get_profile_name(sb);
struct config_llog_instance *cfg;
/* %p for void* in printf needs 16+2 characters: 0xffffffffffffffff */
- const int instlen = 16 + 2;
+ const int instlen = LUSTRE_MAXINSTANCE + 2;
unsigned long cfg_instance = ll_get_cfg_instance(sb);
char name[MAX_STRING_SIZE];
int md_len = 0;
CDEBUG(D_VFSTRACE, "VFS Op: cfg_instance %s-%016lx (sb %p)\n",
profilenm, cfg_instance, sb);
- try_module_get(THIS_MODULE);
-
OBD_ALLOC_PTR(cfg);
if (cfg == NULL)
GOTO(out_free_cfg, err = -ENOMEM);
snprintf(md, md_len - 1, "%s-%016lx", lprof->lp_md, cfg_instance);
/* connections, registrations, sb setup */
- err = client_common_fill_super(sb, md, dt, mnt);
+ err = client_common_fill_super(sb, md, dt);
if (err < 0)
GOTO(out_free_md, err);
/* Wait for unstable pages to be committed to stable storage */
if (force == 0) {
- struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
- rc = l_wait_event(sbi->ll_cache->ccc_unstable_waitq,
- atomic_long_read(&sbi->ll_cache->ccc_unstable_nr) == 0,
- &lwi);
+ rc = l_wait_event_abortable(
+ sbi->ll_cache->ccc_unstable_waitq,
+ atomic_long_read(&sbi->ll_cache->ccc_unstable_nr) == 0);
}
ccc_count = atomic_long_read(&sbi->ll_cache->ccc_unstable_nr);
- if (force == 0 && rc != -EINTR)
+ if (force == 0 && rc != -ERESTARTSYS)
LASSERTF(ccc_count == 0, "count: %li\n", ccc_count);
/* We need to set force before the lov_disconnect in
{
struct ll_inode_info *lli = ll_i2info(inode);
struct lmv_stripe_md *lsm = md->lmv;
+ struct cl_attr *attr;
int rc = 0;
ENTRY;
* normally dir layout doesn't change, only take read lock to check
* that to avoid blocking other MD operations.
*/
- if (lli->lli_lsm_md)
- down_read(&lli->lli_lsm_sem);
- else
- down_write(&lli->lli_lsm_sem);
+ down_read(&lli->lli_lsm_sem);
- /*
- * if dir layout mismatch, check whether version is increased, which
- * means layout is changed, this happens in dir migration and lfsck.
+ /* some current lookup initialized lsm, and unchanged */
+ if (lli->lli_lsm_md && lsm_md_eq(lli->lli_lsm_md, lsm))
+ GOTO(unlock, rc = 0);
+
+ /* if dir layout doesn't match, check whether version is increased,
+ * which means layout is changed, this happens in dir split/merge and
+ * lfsck.
*
* foreign LMV should not change.
*/
- if (lli->lli_lsm_md && !lsm_md_eq(lli->lli_lsm_md, lsm)) {
- if (lmv_dir_striped(lli->lli_lsm_md) &&
- lsm->lsm_md_layout_version <=
- lli->lli_lsm_md->lsm_md_layout_version) {
- CERROR("%s: "DFID" dir layout mismatch:\n",
- ll_i2sbi(inode)->ll_fsname,
- PFID(&lli->lli_fid));
- lsm_md_dump(D_ERROR, lli->lli_lsm_md);
- lsm_md_dump(D_ERROR, lsm);
- GOTO(unlock, rc = -EINVAL);
- }
+ if (lli->lli_lsm_md && lmv_dir_striped(lli->lli_lsm_md) &&
+ lsm->lsm_md_layout_version <=
+ lli->lli_lsm_md->lsm_md_layout_version) {
+ CERROR("%s: "DFID" dir layout mismatch:\n",
+ ll_i2sbi(inode)->ll_fsname, PFID(&lli->lli_fid));
+ lsm_md_dump(D_ERROR, lli->lli_lsm_md);
+ lsm_md_dump(D_ERROR, lsm);
+ GOTO(unlock, rc = -EINVAL);
+ }
- /* layout changed, switch to write lock */
- up_read(&lli->lli_lsm_sem);
- down_write(&lli->lli_lsm_sem);
- ll_dir_clear_lsm_md(inode);
+ up_read(&lli->lli_lsm_sem);
+ down_write(&lli->lli_lsm_sem);
+ /* clear existing lsm */
+ if (lli->lli_lsm_md) {
+ lmv_free_memmd(lli->lli_lsm_md);
+ lli->lli_lsm_md = NULL;
}
- /* set directory layout */
- if (!lli->lli_lsm_md) {
- struct cl_attr *attr;
+ rc = ll_init_lsm_md(inode, md);
+ up_write(&lli->lli_lsm_sem);
- rc = ll_init_lsm_md(inode, md);
- up_write(&lli->lli_lsm_sem);
- if (rc != 0)
- RETURN(rc);
+ if (rc)
+ RETURN(rc);
- /* set md->lmv to NULL, so the following free lustre_md
- * will not free this lsm */
- md->lmv = NULL;
+ /* set md->lmv to NULL, so the following free lustre_md will not free
+ * this lsm.
+ */
+ md->lmv = NULL;
- /*
- * md_merge_attr() may take long, since lsm is already set,
- * switch to read lock.
- */
- down_read(&lli->lli_lsm_sem);
+ /* md_merge_attr() may take long, since lsm is already set, switch to
+ * read lock.
+ */
+ down_read(&lli->lli_lsm_sem);
- if (!lmv_dir_striped(lli->lli_lsm_md))
- GOTO(unlock, rc);
+ if (!lmv_dir_striped(lli->lli_lsm_md))
+ GOTO(unlock, rc = 0);
- OBD_ALLOC_PTR(attr);
- if (attr == NULL)
- GOTO(unlock, rc = -ENOMEM);
-
- /* validate the lsm */
- rc = md_merge_attr(ll_i2mdexp(inode), lsm, attr,
- ll_md_blocking_ast);
- if (rc != 0) {
- OBD_FREE_PTR(attr);
- GOTO(unlock, rc);
- }
+ OBD_ALLOC_PTR(attr);
+ if (!attr)
+ GOTO(unlock, rc = -ENOMEM);
+ /* validate the lsm */
+ rc = md_merge_attr(ll_i2mdexp(inode), lli->lli_lsm_md, attr,
+ ll_md_blocking_ast);
+ if (!rc) {
if (md->body->mbo_valid & OBD_MD_FLNLINK)
md->body->mbo_nlink = attr->cat_nlink;
if (md->body->mbo_valid & OBD_MD_FLSIZE)
md->body->mbo_ctime = attr->cat_ctime;
if (md->body->mbo_valid & OBD_MD_FLMTIME)
md->body->mbo_mtime = attr->cat_mtime;
-
- OBD_FREE_PTR(attr);
}
+
+ OBD_FREE_PTR(attr);
+ GOTO(unlock, rc);
unlock:
up_read(&lli->lli_lsm_sem);
- RETURN(rc);
+ return rc;
}
void ll_clear_inode(struct inode *inode)
(s64)attr->ia_mtime.tv_sec, (s64)attr->ia_ctime.tv_sec,
ktime_get_real_seconds());
- if (S_ISREG(inode->i_mode)) {
- if (attr->ia_valid & ATTR_SIZE)
- inode_dio_write_done(inode);
+ if (S_ISREG(inode->i_mode))
inode_unlock(inode);
- }
/* We always do an MDS RPC, even if we're only changing the size;
* only the MDS knows whether truncate() should fail with -ETXTBUSY */
}
if (attr->ia_valid & ATTR_FILE) {
- struct ll_file_data *fd = LUSTRE_FPRIVATE(attr->ia_file);
+ struct ll_file_data *fd = attr->ia_file->private_data;
if (fd->fd_lease_och)
op_data->op_bias |= MDS_TRUNC_KEEP_LEASE;
/* cleanup will be done if necessary */
md_free_lustre_md(sbi->ll_md_exp, &md);
- if (rc != 0 && it != NULL && it->it_op & IT_OPEN)
+ if (rc != 0 && it != NULL && it->it_op & IT_OPEN) {
+ ll_intent_drop_lock(it);
ll_open_cleanup(sb != NULL ? sb : (*inode)->i_sb, req);
+ }
return rc;
}
OBD_FREE_PTR(op_data);
}
-#ifdef HAVE_SUPEROPS_USE_DENTRY
int ll_show_options(struct seq_file *seq, struct dentry *dentry)
-#else
-int ll_show_options(struct seq_file *seq, struct vfsmount *vfs)
-#endif
{
struct ll_sb_info *sbi;
-#ifdef HAVE_SUPEROPS_USE_DENTRY
- LASSERT((seq != NULL) && (dentry != NULL));
+ LASSERT(seq && dentry);
sbi = ll_s2sbi(dentry->d_sb);
-#else
- LASSERT((seq != NULL) && (vfs != NULL));
- sbi = ll_s2sbi(vfs->mnt_sb);
-#endif
if (sbi->ll_flags & LL_SBI_NOLCK)
seq_puts(seq, ",nolock");