si_meminfo(&si);
pages = si.totalram - si.totalhigh;
- if (pages >> (20 - PAGE_CACHE_SHIFT) < 512) {
- lru_page_max = pages / 2;
- } else {
- lru_page_max = (pages / 4) * 3;
- }
+ lru_page_max = pages / 2;
- /* initialize lru data */
+ /* initialize ll_cache data */
cfs_atomic_set(&sbi->ll_cache.ccc_users, 0);
sbi->ll_cache.ccc_lru_max = lru_page_max;
cfs_atomic_set(&sbi->ll_cache.ccc_lru_left, lru_page_max);
spin_lock_init(&sbi->ll_cache.ccc_lru_lock);
CFS_INIT_LIST_HEAD(&sbi->ll_cache.ccc_lru);
+ cfs_atomic_set(&sbi->ll_cache.ccc_unstable_nr, 0);
+ init_waitqueue_head(&sbi->ll_cache.ccc_unstable_waitq);
+
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;
RETURN(-ENOMEM);
}
- if (proc_lustre_fs_root) {
- err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb,
- dt, md);
- if (err < 0)
- CERROR("could not register mount in /proc/fs/lustre\n");
- }
-
/* indicate the features supported by this client */
data->ocd_connect_flags = OBD_CONNECT_IBITS | OBD_CONNECT_NODEVOH |
OBD_CONNECT_ATTRFID |
OBD_CONNECT_JOBSTATS | OBD_CONNECT_LVB_TYPE |
OBD_CONNECT_LAYOUTLOCK | OBD_CONNECT_PINGLESS |
OBD_CONNECT_MAX_EASIZE |
- OBD_CONNECT_FLOCK_DEAD;
+ OBD_CONNECT_FLOCK_DEAD |
+ OBD_CONNECT_DISP_STRIPE;
if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
data->ocd_connect_flags |= OBD_CONNECT_SOM;
else
sbi->ll_md_brw_size = PAGE_CACHE_SIZE;
- if (data->ocd_connect_flags & OBD_CONNECT_LAYOUTLOCK) {
- LCONSOLE_INFO("Layout lock feature supported.\n");
+ if (data->ocd_connect_flags & OBD_CONNECT_LAYOUTLOCK)
sbi->ll_flags |= LL_SBI_LAYOUT_LOCK;
- }
if (data->ocd_ibits_known & MDS_INODELOCK_XATTR) {
if (!(data->ocd_connect_flags & OBD_CONNECT_MAX_EASIZE)) {
/* make root inode
* XXX: move this to after cbd setup? */
- valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMDSCAPA;
+ valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMDSCAPA |
+ OBD_MD_FLMODEASIZE;
if (sbi->ll_flags & LL_SBI_RMT_CLIENT)
valid |= OBD_MD_FLRMTPERM;
else if (sbi->ll_flags & LL_SBI_ACL)
/* s_dev is also used in lt_compare() to compare two fs, but that is
* only a node-local comparison. */
uuid = obd_get_uuid(sbi->ll_md_exp);
- if (uuid != NULL) {
+ if (uuid != NULL)
sb->s_dev = get_uuid2int(uuid->uuid, strlen(uuid->uuid));
- get_uuid2fsid(uuid->uuid, strlen(uuid->uuid), &sbi->ll_fsid);
- }
if (data != NULL)
OBD_FREE_PTR(data);
if (osfs != NULL)
OBD_FREE_PTR(osfs);
+ if (proc_lustre_fs_root != NULL) {
+ err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb,
+ dt, md);
+ if (err < 0) {
+ CERROR("%s: could not register mount in lprocfs: "
+ "rc = %d\n", ll_get_fsname(sb, NULL, 0), err);
+ err = 0;
+ }
+ }
RETURN(err);
out_root:
OBD_FREE_PTR(data);
if (osfs != NULL)
OBD_FREE_PTR(osfs);
- lprocfs_unregister_mountpoint(sbi);
return err;
}
ll_d_hlist_for_each(tmp, &inode->i_dentry)
dentry_count++;
- CERROR("inode %p dump: dev=%s ino=%lu mode=%o count=%u, %d dentries\n",
- inode, ll_i2mdexp(inode)->exp_obd->obd_name, inode->i_ino,
+ CERROR("%s: inode %p dump: dev=%s fid="DFID
+ " mode=%o count=%u, %d dentries\n",
+ ll_get_fsname(inode->i_sb, NULL, 0), inode,
+ ll_i2mdexp(inode)->exp_obd->obd_name, PFID(ll_inode2fid(inode)),
inode->i_mode, atomic_read(&inode->i_count), dentry_count);
}
" flags=0x%x, fsdata=%p, %d subdirs\n", dentry,
dentry->d_name.len, dentry->d_name.name,
dentry->d_parent->d_name.len, dentry->d_parent->d_name.name,
- dentry->d_parent, dentry->d_inode, d_refcount(dentry),
+ dentry->d_parent, dentry->d_inode, d_count(dentry),
dentry->d_flags, dentry->d_fsdata, subdirs);
if (dentry->d_inode != NULL)
ll_dump_inode(dentry->d_inode);
*flags &= ~tmp;
goto next;
}
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 5, 50, 0)
- tmp = ll_set_opt("acl", s1, LL_SBI_ACL);
- if (tmp) {
- /* Ignore deprecated mount option. The client will
- * always try to mount with ACL support, whether this
- * is used depends on whether server supports it. */
- LCONSOLE_ERROR_MSG(0x152, "Ignoring deprecated "
- "mount option 'acl'.\n");
- goto next;
- }
- tmp = ll_set_opt("noacl", s1, LL_SBI_ACL);
- if (tmp) {
- LCONSOLE_ERROR_MSG(0x152, "Ignoring deprecated "
- "mount option 'noacl'.\n");
- goto next;
- }
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 6, 51, 0)
+ tmp = ll_set_opt("acl", s1, LL_SBI_ACL);
+ if (tmp) {
+ /* Ignore deprecated mount option. The client will
+ * always try to mount with ACL support, whether this
+ * is used depends on whether server supports it. */
+ LCONSOLE_ERROR_MSG(0x152, "Ignoring deprecated "
+ "mount option 'acl'.\n");
+ goto next;
+ }
+ tmp = ll_set_opt("noacl", s1, LL_SBI_ACL);
+ if (tmp) {
+ LCONSOLE_ERROR_MSG(0x152, "Ignoring deprecated "
+ "mount option 'noacl'.\n");
+ goto next;
+ }
#else
#warning "{no}acl options have been deprecated since 1.8, please remove them"
#endif
if (cfg == NULL)
RETURN(-ENOMEM);
- cfs_module_get();
+ try_module_get(THIS_MODULE);
- /* client additional sb info */
- lsi->lsi_llsbi = sbi = ll_init_sbi();
- if (!sbi) {
- cfs_module_put(THIS_MODULE);
- OBD_FREE_PTR(cfg);
- RETURN(-ENOMEM);
- }
+ /* client additional sb info */
+ lsi->lsi_llsbi = sbi = ll_init_sbi();
+ if (!sbi) {
+ module_put(THIS_MODULE);
+ OBD_FREE_PTR(cfg);
+ RETURN(-ENOMEM);
+ }
err = ll_options(lsi->lsi_lmd->lmd_opts, &sbi->ll_flags);
if (err)
cfg->cfg_callback = class_config_llog_handler;
/* set up client obds */
err = lustre_process_log(sb, profilenm, cfg);
- if (err < 0) {
- CERROR("Unable to process log: %d\n", err);
- GOTO(out_free, err);
- }
+ if (err < 0)
+ GOTO(out_free, err);
/* Profile set with LCFG_MOUNTOPT so we can find our mdc and osc obds */
lprof = class_get_profile(profilenm);
struct lustre_sb_info *lsi = s2lsi(sb);
struct ll_sb_info *sbi = ll_s2sbi(sb);
char *profilenm = get_profile_name(sb);
- int force = 1, next;
+ int ccc_count, next, force = 1, rc = 0;
ENTRY;
CDEBUG(D_VFSTRACE, "VFS Op: sb %p - %s\n", sb, profilenm);
force = obd->obd_force;
}
+ /* 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,
+ cfs_atomic_read(&sbi->ll_cache.ccc_unstable_nr) == 0,
+ &lwi);
+ }
+
+ ccc_count = cfs_atomic_read(&sbi->ll_cache.ccc_unstable_nr);
+ if (force == 0 && rc != -EINTR)
+ LASSERTF(ccc_count == 0, "count: %i\n", ccc_count);
+
+
/* We need to set force before the lov_disconnect in
lustre_common_put_super, since l_d cleans up osc's as well. */
if (force) {
ll_free_sbi(sb);
lsi->lsi_llsbi = NULL;
- lustre_common_put_super(sb);
+ lustre_common_put_super(sb);
- cfs_module_put(THIS_MODULE);
+ cl_env_cache_purge(~0);
- EXIT;
+ module_put(THIS_MODULE);
+
+ EXIT;
} /* client_put_super */
struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock)
return inode;
}
+static void ll_dir_clear_lsm_md(struct inode *inode)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+
+ LASSERT(S_ISDIR(inode->i_mode));
+
+ if (lli->lli_lsm_md != NULL) {
+ lmv_free_memmd(lli->lli_lsm_md);
+ lli->lli_lsm_md = NULL;
+ }
+}
+
+static struct inode *ll_iget_anon_dir(struct super_block *sb,
+ const struct lu_fid *fid,
+ struct lustre_md *md)
+{
+ struct ll_sb_info *sbi = ll_s2sbi(sb);
+ struct mdt_body *body = md->body;
+ struct inode *inode;
+ ino_t ino;
+ ENTRY;
+
+ ino = cl_fid_build_ino(fid, sbi->ll_flags & LL_SBI_32BIT_API);
+ inode = iget_locked(sb, ino);
+ if (inode == NULL) {
+ CERROR("%s: failed get simple inode "DFID": rc = -ENOENT\n",
+ ll_get_fsname(sb, NULL, 0), PFID(fid));
+ RETURN(ERR_PTR(-ENOENT));
+ }
+
+ if (inode->i_state & I_NEW) {
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct lmv_stripe_md *lsm = md->lmv;
+
+ inode->i_mode = (inode->i_mode & ~S_IFMT) |
+ (body->mode & S_IFMT);
+ LASSERTF(S_ISDIR(inode->i_mode), "Not slave inode "DFID"\n",
+ PFID(fid));
+
+ LTIME_S(inode->i_mtime) = 0;
+ LTIME_S(inode->i_atime) = 0;
+ LTIME_S(inode->i_ctime) = 0;
+ inode->i_rdev = 0;
+
+ /* initializing backing dev info. */
+ inode->i_mapping->backing_dev_info =
+ &s2lsi(inode->i_sb)->lsi_bdi;
+ inode->i_op = &ll_dir_inode_operations;
+ inode->i_fop = &ll_dir_operations;
+ lli->lli_fid = *fid;
+ ll_lli_init(lli);
+
+ LASSERT(lsm != NULL);
+ /* master stripe FID */
+ lli->lli_pfid = lsm->lsm_md_oinfo[0].lmo_fid;
+ CDEBUG(D_INODE, "lli %p master "DFID" slave "DFID"\n",
+ lli, PFID(fid), PFID(&lli->lli_pfid));
+ unlock_new_inode(inode);
+ }
+
+ RETURN(inode);
+}
+
+static int ll_init_lsm_md(struct inode *inode, struct lustre_md *md)
+{
+ struct lu_fid *fid;
+ struct lmv_stripe_md *lsm = md->lmv;
+ int i;
+
+ LASSERT(lsm != NULL);
+ /* XXX sigh, this lsm_root initialization should be in
+ * LMV layer, but it needs ll_iget right now, so we
+ * put this here right now. */
+ for (i = 0; i < lsm->lsm_md_stripe_count; i++) {
+ fid = &lsm->lsm_md_oinfo[i].lmo_fid;
+ LASSERT(lsm->lsm_md_oinfo[i].lmo_root == NULL);
+ if (i == 0) {
+ lsm->lsm_md_oinfo[i].lmo_root = inode;
+ } else {
+ /* Unfortunately ll_iget will call ll_update_inode,
+ * where the initialization of slave inode is slightly
+ * different, so it reset lsm_md to NULL to avoid
+ * initializing lsm for slave inode. */
+ lsm->lsm_md_oinfo[i].lmo_root =
+ ll_iget_anon_dir(inode->i_sb, fid, md);
+ if (IS_ERR(lsm->lsm_md_oinfo[i].lmo_root)) {
+ int rc = PTR_ERR(lsm->lsm_md_oinfo[i].lmo_root);
+
+ lsm->lsm_md_oinfo[i].lmo_root = NULL;
+ return rc;
+ }
+ }
+ }
+
+ /* Here is where the lsm is being initialized(fill lmo_info) after
+ * client retrieve MD stripe information from MDT. */
+ return md_update_lsm_md(ll_i2mdexp(inode), lsm, md->body,
+ ll_md_blocking_ast);
+}
+
+static inline int lli_lsm_md_eq(const struct lmv_stripe_md *lsm_md1,
+ const struct lmv_stripe_md *lsm_md2)
+{
+ return lsm_md1->lsm_md_magic == lsm_md2->lsm_md_magic &&
+ lsm_md1->lsm_md_stripe_count == lsm_md2->lsm_md_stripe_count &&
+ lsm_md1->lsm_md_master_mdt_index ==
+ lsm_md2->lsm_md_master_mdt_index &&
+ lsm_md1->lsm_md_hash_type == lsm_md2->lsm_md_hash_type &&
+ lsm_md1->lsm_md_layout_version ==
+ lsm_md2->lsm_md_layout_version &&
+ strcmp(lsm_md1->lsm_md_pool_name,
+ lsm_md2->lsm_md_pool_name) == 0;
+}
+
+static void ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct lmv_stripe_md *lsm = md->lmv;
+ int idx;
+ ENTRY;
+
+ LASSERT(S_ISDIR(inode->i_mode));
+ CDEBUG(D_INODE, "update lsm %p of "DFID"\n", lli->lli_lsm_md,
+ PFID(ll_inode2fid(inode)));
+
+ /* no striped information from request. */
+ if (lsm == NULL) {
+ if (lli->lli_lsm_md == NULL) {
+ RETURN_EXIT;
+ } else if (lli->lli_lsm_md->lsm_md_magic == LMV_MAGIC_MIGRATE) {
+ /* migration is done, the temporay MIGRATE layout has
+ * been removed */
+ CDEBUG(D_INODE, DFID" finish migration.\n",
+ PFID(ll_inode2fid(inode)));
+ lmv_free_memmd(lli->lli_lsm_md);
+ lli->lli_lsm_md = NULL;
+ RETURN_EXIT;
+ } else {
+ /* The lustre_md from req does not include stripeEA,
+ * see ll_md_setattr */
+ RETURN_EXIT;
+ }
+ }
+
+ /* set the directory layout */
+ if (lli->lli_lsm_md == NULL) {
+ int rc;
+
+ rc = ll_init_lsm_md(inode, md);
+ if (rc != 0) {
+ CERROR("%s: init "DFID" failed: rc = %d\n",
+ ll_get_fsname(inode->i_sb, NULL, 0),
+ PFID(&lli->lli_fid), rc);
+ return;
+ }
+ lli->lli_lsm_md = lsm;
+ /* set lsm_md to NULL, so the following free lustre_md
+ * will not free this lsm */
+ md->lmv = NULL;
+ CDEBUG(D_INODE, "Set lsm %p magic %x to "DFID"\n", lsm,
+ lsm->lsm_md_magic, PFID(ll_inode2fid(inode)));
+ RETURN_EXIT;
+ }
+
+ /* Compare the old and new stripe information */
+ if (!lli_lsm_md_eq(lli->lli_lsm_md, lsm)) {
+ CERROR("inode %p %lu mismatch\n"
+ " new(%p) vs lli_lsm_md(%p):\n"
+ " magic: %x %x\n"
+ " count: %x %x\n"
+ " master: %x %x\n"
+ " hash_type: %x %x\n"
+ " layout: %x %x\n"
+ " pool: %s %s\n",
+ inode, inode->i_ino, lsm, lli->lli_lsm_md,
+ lsm->lsm_md_magic, lli->lli_lsm_md->lsm_md_magic,
+ lsm->lsm_md_stripe_count,
+ lli->lli_lsm_md->lsm_md_stripe_count,
+ lsm->lsm_md_master_mdt_index,
+ lli->lli_lsm_md->lsm_md_master_mdt_index,
+ lsm->lsm_md_hash_type, lli->lli_lsm_md->lsm_md_hash_type,
+ lsm->lsm_md_layout_version,
+ lli->lli_lsm_md->lsm_md_layout_version,
+ lsm->lsm_md_pool_name,
+ lli->lli_lsm_md->lsm_md_pool_name);
+ return;
+ }
+
+ for (idx = 0; idx < lli->lli_lsm_md->lsm_md_stripe_count; idx++) {
+ if (!lu_fid_eq(&lli->lli_lsm_md->lsm_md_oinfo[idx].lmo_fid,
+ &lsm->lsm_md_oinfo[idx].lmo_fid)) {
+ CERROR("%s: FID in lsm mismatch idx %d, old: "DFID
+ "new:"DFID"\n",
+ ll_get_fsname(inode->i_sb, NULL, 0), idx,
+ PFID(&lli->lli_lsm_md->lsm_md_oinfo[idx].lmo_fid),
+ PFID(&lsm->lsm_md_oinfo[idx].lmo_fid));
+ return;
+ }
+ }
+
+ md_update_lsm_md(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
+ md->body, ll_md_blocking_ast);
+
+ RETURN_EXIT;
+}
+
void ll_clear_inode(struct inode *inode)
{
struct ll_inode_info *lli = ll_i2info(inode);
struct ll_sb_info *sbi = ll_i2sbi(inode);
ENTRY;
- CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
- inode->i_generation, inode);
+ CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p)\n",
+ PFID(ll_inode2fid(inode)), inode);
if (S_ISDIR(inode->i_mode)) {
/* these should have been cleared in ll_file_release */
#endif
lli->lli_inode_magic = LLI_INODE_DEAD;
- ll_clear_inode_capas(inode);
- if (!S_ISDIR(inode->i_mode))
- LASSERT(cfs_list_empty(&lli->lli_agl_list));
+ ll_clear_inode_capas(inode);
+ if (S_ISDIR(inode->i_mode))
+ ll_dir_clear_lsm_md(inode);
+ else
+ LASSERT(list_empty(&lli->lli_agl_list));
- /*
- * XXX This has to be done before lsm is freed below, because
- * cl_object still uses inode lsm.
- */
- cl_inode_fini(inode);
+ /*
+ * XXX This has to be done before lsm is freed below, because
+ * cl_object still uses inode lsm.
+ */
+ cl_inode_fini(inode);
lli->lli_has_smd = false;
EXIT;
* from OSTs and send setattr to back to MDS. */
rc = ll_som_update(inode, op_data);
} else if (rc) {
- CERROR("inode %lu mdc truncate failed: rc = %d\n",
- inode->i_ino, rc);
+ CERROR("%s: inode "DFID" mdc truncate failed: rc = %d\n",
+ ll_i2sbi(inode)->ll_md_exp->exp_obd->obd_name,
+ PFID(ll_inode2fid(inode)), rc);
}
RETURN(rc);
}
struct md_op_data *op_data = NULL;
struct md_open_data *mod = NULL;
bool file_is_released = false;
- int rc = 0, rc1 = 0;
- ENTRY;
+ int rc = 0, rc1 = 0;
+ ENTRY;
- CDEBUG(D_VFSTRACE, "%s: setattr inode %p/fid:"DFID" from %llu to %llu, "
- "valid %x, hsm_import %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0), inode,
- PFID(&lli->lli_fid), i_size_read(inode), attr->ia_size,
- attr->ia_valid, hsm_import);
+ CDEBUG(D_VFSTRACE, "%s: setattr inode "DFID"(%p) from %llu to %llu, "
+ "valid %x, hsm_import %d\n",
+ ll_get_fsname(inode->i_sb, NULL, 0), PFID(&lli->lli_fid),
+ inode, i_size_read(inode), attr->ia_size, attr->ia_valid,
+ hsm_import);
if (attr->ia_valid & ATTR_SIZE) {
/* Check new size against VFS/VM file size limit and rlimit */
attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
}
- /* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */
+ /* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */
if (attr->ia_valid & TIMES_SET_FLAGS) {
- if (cfs_curproc_fsuid() != inode->i_uid &&
- !cfs_capable(CFS_CAP_FOWNER))
- RETURN(-EPERM);
- }
+ if (current_fsuid() != inode->i_uid &&
+ !cfs_capable(CFS_CAP_FOWNER))
+ RETURN(-EPERM);
+ }
/* We mark all of the fields "set" so MDS/OST does not re-set them */
if (attr->ia_valid & ATTR_CTIME) {
LTIME_S(attr->ia_mtime), LTIME_S(attr->ia_ctime),
cfs_time_current_sec());
- /* If we are changing file size, file content is modified, flag it. */
- if (attr->ia_valid & ATTR_SIZE) {
- attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE;
- spin_lock(&lli->lli_lock);
- lli->lli_flags |= LLIF_DATA_MODIFIED;
- spin_unlock(&lli->lli_lock);
- }
-
/* We always do an MDS RPC, even if we're only changing the size;
* only the MDS knows whether truncate() should fail with -ETXTBUSY */
down_write(&lli->lli_trunc_sem);
}
- memcpy(&op_data->op_attr, attr, sizeof(*attr));
-
- /* Open epoch for truncate. */
- if (exp_connect_som(ll_i2mdexp(inode)) &&
- (attr->ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MTIME_SET)))
- op_data->op_flags = MF_EPOCH_OPEN;
-
/* truncate on a released file must failed with -ENODATA,
* so size must not be set on MDS for released file
* but other attributes must be set
if (lsm && lsm->lsm_pattern & LOV_PATTERN_F_RELEASED)
file_is_released = true;
ccc_inode_lsm_put(inode, lsm);
- }
- /* if not in HSM import mode, clear size attr for released file
- * we clear the attribute send to MDT in op_data, not the original
- * received from caller in attr which is used later to
- * decide return code */
- if (file_is_released && (attr->ia_valid & ATTR_SIZE) && !hsm_import)
- op_data->op_attr.ia_valid &= ~ATTR_SIZE;
+ if (!hsm_import && attr->ia_valid & ATTR_SIZE) {
+ if (file_is_released) {
+ rc = ll_layout_restore(inode, 0, attr->ia_size);
+ if (rc < 0)
+ GOTO(out, rc);
- rc = ll_md_setattr(dentry, op_data, &mod);
- if (rc)
- GOTO(out, rc);
+ file_is_released = false;
+ ll_layout_refresh(inode, &gen);
+ }
- /* truncate failed (only when non HSM import), others succeed */
- if (file_is_released) {
- if ((attr->ia_valid & ATTR_SIZE) && !hsm_import)
- GOTO(out, rc = -ENODATA);
- else
- GOTO(out, rc = 0);
+ /* If we are changing file size, file content is
+ * modified, flag it. */
+ attr->ia_valid |= MDS_OPEN_OWNEROVERRIDE;
+ spin_lock(&lli->lli_lock);
+ lli->lli_flags |= LLIF_DATA_MODIFIED;
+ spin_unlock(&lli->lli_lock);
+ op_data->op_bias |= MDS_DATA_MODIFIED;
+ }
}
+ memcpy(&op_data->op_attr, attr, sizeof(*attr));
+
+ /* Open epoch for truncate. */
+ if (exp_connect_som(ll_i2mdexp(inode)) && !hsm_import &&
+ (attr->ia_valid & (ATTR_SIZE | ATTR_MTIME | ATTR_MTIME_SET)))
+ op_data->op_flags = MF_EPOCH_OPEN;
+
+ rc = ll_md_setattr(dentry, op_data, &mod);
+ if (rc)
+ GOTO(out, rc);
+
/* RPC to MDT is sent, cancel data modification flag */
if (rc == 0 && (op_data->op_bias & MDS_DATA_MODIFIED)) {
spin_lock(&lli->lli_lock);
spin_unlock(&lli->lli_lock);
}
- ll_ioepoch_open(lli, op_data->op_ioepoch);
- if (!S_ISREG(inode->i_mode))
- GOTO(out, rc = 0);
+ ll_ioepoch_open(lli, op_data->op_ioepoch);
+ if (!S_ISREG(inode->i_mode) || file_is_released)
+ GOTO(out, rc = 0);
if (attr->ia_valid & (ATTR_SIZE |
ATTR_ATIME | ATTR_ATIME_SET |
ATTR_MTIME | ATTR_MTIME_SET)) {
- /* 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);
+ /* 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;
+ EXIT;
out:
- if (op_data) {
- 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 (op_data) {
+ 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)) {
up_write(&lli->lli_trunc_sem);
mutex_lock(&inode->i_mutex);
{
struct super_block *sb = de->d_sb;
struct obd_statfs osfs;
+ __u64 fsid = huge_encode_dev(sb->s_dev);
int rc;
CDEBUG(D_VFSTRACE, "VFS Op: at "LPU64" jiffies\n", get_jiffies_64());
sfs->f_blocks = osfs.os_blocks;
sfs->f_bfree = osfs.os_bfree;
sfs->f_bavail = osfs.os_bavail;
- sfs->f_fsid = ll_s2sbi(sb)->ll_fsid;
+ sfs->f_fsid.val[0] = (__u32)fsid;
+ sfs->f_fsid.val[1] = (__u32)(fsid >> 32);
return 0;
}
lli->lli_maxbytes = MAX_LFS_FILESIZE;
}
- if (sbi->ll_flags & LL_SBI_RMT_CLIENT) {
+ if (S_ISDIR(inode->i_mode))
+ ll_update_lsm_md(inode, md);
+
+ if (sbi->ll_flags & LL_SBI_RMT_CLIENT) {
if (body->valid & OBD_MD_FLRMTPERM)
ll_update_remote_perm(inode, md->remote_perm);
}
#endif
inode->i_ino = cl_fid_build_ino(&body->fid1,
sbi->ll_flags & LL_SBI_32BIT_API);
- inode->i_generation = cl_fid_build_gen(&body->fid1);
+ inode->i_generation = cl_fid_build_gen(&body->fid1);
if (body->valid & OBD_MD_FLATIME) {
if (body->atime > LTIME_S(inode->i_atime))
if (body->valid & OBD_MD_FLRDEV)
inode->i_rdev = old_decode_dev(body->rdev);
- if (body->valid & OBD_MD_FLID) {
- /* FID shouldn't be changed! */
- if (fid_is_sane(&lli->lli_fid)) {
- LASSERTF(lu_fid_eq(&lli->lli_fid, &body->fid1),
- "Trying to change FID "DFID
- " to the "DFID", inode %lu/%u(%p)\n",
- PFID(&lli->lli_fid), PFID(&body->fid1),
- inode->i_ino, inode->i_generation, inode);
- } else
- lli->lli_fid = body->fid1;
- }
+ if (body->valid & OBD_MD_FLID) {
+ /* FID shouldn't be changed! */
+ if (fid_is_sane(&lli->lli_fid)) {
+ LASSERTF(lu_fid_eq(&lli->lli_fid, &body->fid1),
+ "Trying to change FID "DFID
+ " to the "DFID", inode "DFID"(%p)\n",
+ PFID(&lli->lli_fid), PFID(&body->fid1),
+ PFID(ll_inode2fid(inode)), inode);
+ } else {
+ lli->lli_fid = body->fid1;
+ }
+ }
LASSERT(fid_seq(&lli->lli_fid) != 0);
if (lli->lli_flags & (LLIF_DONE_WRITING |
LLIF_EPOCH_PENDING |
LLIF_SOM_DIRTY)) {
- CERROR("ino %lu flags %u still has "
- "size authority! do not trust "
- "the size got from MDS\n",
- inode->i_ino, lli->lli_flags);
+ CERROR("%s: inode "DFID" flags %u still"
+ " has size authority! do not "
+ "trust the size from MDS\n",
+ sbi->ll_md_exp->exp_obd->obd_name,
+ PFID(ll_inode2fid(inode)),
+ lli->lli_flags);
} else {
/* Use old size assignment to avoid
* deadlock bz14138 & bz14326 */
* deadlock bz14138 & bz14326 */
i_size_write(inode, body->size);
- CDEBUG(D_VFSTRACE, "inode=%lu, updating i_size %llu\n",
- inode->i_ino, (unsigned long long)body->size);
+ CDEBUG(D_VFSTRACE,
+ "inode="DFID", updating i_size %llu\n",
+ PFID(ll_inode2fid(inode)),
+ (unsigned long long)body->size);
}
if (body->valid & OBD_MD_FLBLOCKS)
/* Workaround for LU-118 */
if (inode->i_data.nrpages) {
- TREE_READ_LOCK_IRQ(&inode->i_data);
- TREE_READ_UNLOCK_IRQ(&inode->i_data);
+ spin_lock_irq(&inode->i_data.tree_lock);
+ spin_unlock_irq(&inode->i_data.tree_lock);
LASSERTF(inode->i_data.nrpages == 0,
- "inode=%lu/%u(%p) nrpages=%lu, see "
- "http://jira.whamcloud.com/browse/LU-118\n",
- inode->i_ino, inode->i_generation, inode,
+ "inode="DFID"(%p) nrpages=%lu, see "
+ "http://jira.whamcloud.com/browse/LU-118\n",
+ PFID(ll_inode2fid(inode)), inode,
inode->i_data.nrpages);
}
/* Workaround end */
rc = md_getattr(sbi->ll_md_exp, op_data, &req);
ll_finish_md_op_data(op_data);
if (rc) {
- CERROR("failure %d inode %lu\n", rc, inode->i_ino);
+ CERROR("%s: failure inode "DFID": rc = %d\n",
+ sbi->ll_md_exp->exp_obd->obd_name,
+ PFID(ll_inode2fid(inode)), rc);
RETURN(-abs(rc));
}
int ll_flush_ctx(struct inode *inode)
{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
- CDEBUG(D_SEC, "flush context for user %d\n", cfs_curproc_uid());
+ CDEBUG(D_SEC, "flush context for user %d\n", current_uid());
- obd_set_info_async(NULL, sbi->ll_md_exp,
- sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
- 0, NULL, NULL);
- obd_set_info_async(NULL, sbi->ll_dt_exp,
- sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
- 0, NULL, NULL);
- return 0;
+ obd_set_info_async(NULL, sbi->ll_md_exp,
+ sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
+ 0, NULL, NULL);
+ obd_set_info_async(NULL, sbi->ll_dt_exp,
+ sizeof(KEY_FLUSH_CTX), KEY_FLUSH_CTX,
+ 0, NULL, NULL);
+ return 0;
}
/* umount -f client means force down, don't save state */
OBD_FREE_PTR(ioc_data);
}
- /* Really, we'd like to wait until there are no requests outstanding,
- * and then continue. For now, we just invalidate the requests,
- * schedule() and sleep one second if needed, and hope.
- */
- cfs_schedule();
- EXIT;
+ /* Really, we'd like to wait until there are no requests outstanding,
+ * and then continue. For now, we just invalidate the requests,
+ * schedule() and sleep one second if needed, and hope.
+ */
+ schedule();
+ EXIT;
}
int ll_remount_fs(struct super_block *sb, int *flags, char *data)
struct super_block *sb, struct lookup_intent *it)
{
struct ll_sb_info *sbi = NULL;
- struct lustre_md md;
- int rc;
- ENTRY;
+ struct lustre_md md = { 0 };
+ int rc;
+ ENTRY;
LASSERT(*inode || sb);
sbi = sb ? ll_s2sbi(sb) : ll_i2sbi(*inode);
int ll_process_config(struct lustre_cfg *lcfg)
{
- char *ptr;
- void *sb;
- struct lprocfs_static_vars lvars;
- unsigned long x;
- int rc = 0;
+ struct super_block *sb;
+ unsigned long x;
+ int rc = 0;
+ char *ptr;
- lprocfs_llite_init_vars(&lvars);
-
- /* 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 = (void *)x;
- /* This better be a real Lustre superblock! */
- LASSERT(s2lsi((struct super_block *)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, lvars.obd_vars,
- lcfg, sb);
- if (rc > 0)
- rc = 0;
- return(rc);
+ /* 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_seq_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 ot down to MD stack. */
if (op_data == NULL)
return ERR_PTR(-ENOMEM);
- ll_i2gids(op_data->op_suppgids, i1, i2);
- op_data->op_fid1 = *ll_inode2fid(i1);
- op_data->op_capa1 = ll_mdscapa_get(i1);
+ ll_i2gids(op_data->op_suppgids, i1, i2);
+ op_data->op_fid1 = *ll_inode2fid(i1);
+ op_data->op_capa1 = ll_mdscapa_get(i1);
+ if (S_ISDIR(i1->i_mode))
+ op_data->op_mea1 = ll_i2info(i1)->lli_lsm_md;
+
+ if (i2) {
+ op_data->op_fid2 = *ll_inode2fid(i2);
+ op_data->op_capa2 = ll_mdscapa_get(i2);
+ if (S_ISDIR(i2->i_mode))
+ op_data->op_mea2 = ll_i2info(i2)->lli_lsm_md;
+ } else {
+ fid_zero(&op_data->op_fid2);
+ op_data->op_capa2 = NULL;
+ }
- if (i2) {
- op_data->op_fid2 = *ll_inode2fid(i2);
- op_data->op_capa2 = ll_mdscapa_get(i2);
- } else {
- fid_zero(&op_data->op_fid2);
- op_data->op_capa2 = NULL;
- }
+ if (ll_i2sbi(i1)->ll_flags & LL_SBI_64BIT_HASH)
+ op_data->op_cli_flags |= CLI_HASH64;
+
+ if (ll_need_32bit_api(ll_i2sbi(i1)))
+ op_data->op_cli_flags |= CLI_API32;
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_fsuid = cfs_curproc_fsuid();
- op_data->op_fsgid = cfs_curproc_fsgid();
+ op_data->op_fsuid = current_fsuid();
+ op_data->op_fsgid = current_fsgid();
op_data->op_cap = cfs_curproc_cap_pack();
op_data->op_bias = 0;
op_data->op_cli_flags = 0;
if ((opc == LUSTRE_OPC_CREATE) && (name != NULL) &&
filename_is_volatile(name, namelen, NULL))
op_data->op_bias |= MDS_CREATE_VOLATILE;
- op_data->op_opc = opc;
op_data->op_mds = 0;
op_data->op_data = data;
{
char *path = NULL;
-#ifdef HAVE_FS_STRUCT_USE_PATH
struct path p;
p.dentry = dentry;
path_get(&p);
path = d_path(&p, buf, bufsize);
path_put(&p);
-#else
- path = d_path(dentry, current->fs->rootmnt, buf, bufsize);
-#endif
-
return path;
}