if (class_exp2obd(md_exp) == NULL) {
CERROR("%s: invalid MDC connection handle closing "DFID"\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
- PFID(&lli->lli_fid));
+ ll_i2sbi(inode)->ll_fsname, PFID(&lli->lli_fid));
GOTO(out, rc = 0);
}
struct page *vmpage;
struct niobuf_remote *rnb;
char *data;
- struct lustre_handle lockh;
- struct ldlm_lock *lock;
unsigned long index, start;
struct niobuf_local lnb;
- bool dom_lock = false;
ENTRY;
if (obj == NULL)
RETURN_EXIT;
- if (it->it_lock_mode != 0) {
- lockh.cookie = it->it_lock_handle;
- lock = ldlm_handle2lock(&lockh);
- if (lock != NULL)
- dom_lock = ldlm_has_dom(lock);
- LDLM_LOCK_PUT(lock);
- }
- if (!dom_lock)
- RETURN_EXIT;
-
if (!req_capsule_has_field(&req->rq_pill, &RMF_NIOBUF_INLINE,
RCL_SERVER))
RETURN_EXIT;
*/
if (rnb->rnb_offset + rnb->rnb_len < i_size_read(inode)) {
CERROR("%s: server returns off/len %llu/%u < i_size %llu\n",
- ll_get_fsname(inode->i_sb, NULL, 0), rnb->rnb_offset,
+ ll_i2sbi(inode)->ll_fsname, rnb->rnb_offset,
rnb->rnb_len, i_size_read(inode));
RETURN_EXIT;
}
if (IS_ERR(vmpage)) {
CWARN("%s: cannot fill page %lu for "DFID
" with data: rc = %li\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
- index + start, PFID(lu_object_fid(&obj->co_lu)),
+ ll_i2sbi(inode)->ll_fsname, index + start,
+ PFID(lu_object_fid(&obj->co_lu)),
PTR_ERR(vmpage));
break;
}
{
struct ll_sb_info *sbi = ll_i2sbi(de->d_inode);
struct dentry *parent = de->d_parent;
- const char *name = NULL;
+ char *name = NULL;
int len = 0;
struct md_op_data *op_data;
struct ptlrpc_request *req = NULL;
/* if server supports open-by-fid, or file name is invalid, don't pack
* name in open request */
- if (!(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_OPEN_BY_FID) &&
- lu_name_is_valid_2(de->d_name.name, de->d_name.len)) {
- name = de->d_name.name;
+ if (OBD_FAIL_CHECK(OBD_FAIL_LLITE_OPEN_BY_NAME) ||
+ !(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_OPEN_BY_FID)) {
+retry:
len = de->d_name.len;
+ name = kmalloc(len + 1, GFP_NOFS);
+ if (!name)
+ RETURN(-ENOMEM);
+
+ /* race here */
+ spin_lock(&de->d_lock);
+ if (len != de->d_name.len) {
+ spin_unlock(&de->d_lock);
+ kfree(name);
+ goto retry;
+ }
+ memcpy(name, de->d_name.name, len);
+ name[len] = '\0';
+ spin_unlock(&de->d_lock);
+
+ if (!lu_name_is_valid_2(name, len)) {
+ kfree(name);
+ RETURN(-ESTALE);
+ }
}
op_data = ll_prep_md_op_data(NULL, parent->d_inode, de->d_inode,
name, len, 0, LUSTRE_OPC_ANY, NULL);
- if (IS_ERR(op_data))
+ if (IS_ERR(op_data)) {
+ kfree(name);
RETURN(PTR_ERR(op_data));
+ }
op_data->op_data = lmm;
op_data->op_data_size = lmmsize;
rc = md_intent_lock(sbi->ll_md_exp, op_data, itp, &req,
&ll_md_blocking_ast, 0);
+ kfree(name);
ll_finish_md_op_data(op_data);
if (rc == -ESTALE) {
/* reason for keep own exit path - don`t flood log
rc = ll_prep_inode(&de->d_inode, req, NULL, itp);
if (!rc && itp->it_lock_mode) {
- ll_dom_finish_open(de->d_inode, req, itp);
+ struct lustre_handle handle = {.cookie = itp->it_lock_handle};
+ struct ldlm_lock *lock;
+ bool has_dom_bit = false;
+
+ /* If we got a lock back and it has a LOOKUP bit set,
+ * make sure the dentry is marked as valid so we can find it.
+ * We don't need to care about actual hashing since other bits
+ * of kernel will deal with that later.
+ */
+ lock = ldlm_handle2lock(&handle);
+ if (lock) {
+ has_dom_bit = ldlm_has_dom(lock);
+ if (lock->l_policy_data.l_inodebits.bits &
+ MDS_INODELOCK_LOOKUP)
+ d_lustre_revalidate(de);
+
+ LDLM_LOCK_PUT(lock);
+ }
ll_set_lock_data(sbi->ll_md_exp, de->d_inode, itp, NULL);
+ if (has_dom_bit)
+ ll_dom_finish_open(de->d_inode, req, itp);
}
out:
rc2 = ll_close_inode_openhandle(inode, och, 0, NULL);
if (rc2 < 0)
CERROR("%s: error closing file "DFID": %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
- PFID(&ll_i2info(inode)->lli_fid), rc2);
+ sbi->ll_fsname, PFID(&ll_i2info(inode)->lli_fid), rc2);
och = NULL; /* och has been freed in ll_close_inode_openhandle() */
out_release_it:
ll_intent_release(&it);
ENTRY;
CDEBUG(D_INODE, "%s: biased close of file "DFID"\n",
- ll_get_fsname(inode->i_sb, NULL, 0), PFID(fid1));
+ ll_i2sbi(inode)->ll_fsname, PFID(fid1));
rc = ll_check_swap_layouts_validity(inode, inode2);
if (rc < 0)
* if it's at least 'mdd.*.atime_diff' older.
* All in all, the atime in Lustre does not strictly comply with
* POSIX. Solving this problem needs to send an RPC to MDT for each
- * read, this will hurt performance. */
- if (LTIME_S(inode->i_atime) < lli->lli_atime || lli->lli_update_atime) {
- LTIME_S(inode->i_atime) = lli->lli_atime;
+ * read, this will hurt performance.
+ */
+ if (inode->i_atime.tv_sec < lli->lli_atime ||
+ lli->lli_update_atime) {
+ inode->i_atime.tv_sec = lli->lli_atime;
lli->lli_update_atime = 0;
}
- LTIME_S(inode->i_mtime) = lli->lli_mtime;
- LTIME_S(inode->i_ctime) = lli->lli_ctime;
+ inode->i_mtime.tv_sec = lli->lli_mtime;
+ inode->i_ctime.tv_sec = lli->lli_ctime;
- atime = LTIME_S(inode->i_atime);
- mtime = LTIME_S(inode->i_mtime);
- ctime = LTIME_S(inode->i_ctime);
+ mtime = inode->i_mtime.tv_sec;
+ atime = inode->i_atime.tv_sec;
+ ctime = inode->i_ctime.tv_sec;
cl_object_attr_lock(obj);
if (OBD_FAIL_CHECK(OBD_FAIL_MDC_MERGE))
i_size_write(inode, attr->cat_size);
inode->i_blocks = attr->cat_blocks;
- LTIME_S(inode->i_atime) = atime;
- LTIME_S(inode->i_mtime) = mtime;
- LTIME_S(inode->i_ctime) = ctime;
+ inode->i_mtime.tv_sec = mtime;
+ inode->i_atime.tv_sec = atime;
+ inode->i_ctime.tv_sec = ctime;
out_size_unlock:
ll_inode_size_unlock(inode);
io->ci_ndelay = 0;
io->ci_designated_mirror = fd->fd_designated_mirror;
io->ci_layout_version = fd->fd_layout_version;
- io->ci_pio = 0; /* doesn't have a mechanism to pass mirror
- * io to ptasks */
}
CDEBUG(D_VFSTRACE, "%s: desiginated mirror: %d\n",
return false;
}
-static int ll_file_io_ptask(struct cfs_ptask *ptask);
-
static void ll_io_init(struct cl_io *io, struct file *file, enum cl_io_type iot)
{
struct inode *inode = file_inode(file);
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
- memset(&io->u.ci_rw.rw_iter, 0, sizeof(io->u.ci_rw.rw_iter));
- init_sync_kiocb(&io->u.ci_rw.rw_iocb, file);
- io->u.ci_rw.rw_file = file;
- io->u.ci_rw.rw_ptask = ll_file_io_ptask;
- io->u.ci_rw.rw_nonblock = !!(file->f_flags & O_NONBLOCK);
+ io->u.ci_rw.crw_nonblock = file->f_flags & O_NONBLOCK;
io->ci_lock_no_expand = fd->ll_lock_no_expand;
if (iot == CIT_WRITE) {
- io->u.ci_rw.rw_append = !!(file->f_flags & O_APPEND);
- io->u.ci_rw.rw_sync = !!(file->f_flags & O_SYNC ||
+ io->u.ci_wr.wr_append = !!(file->f_flags & O_APPEND);
+ io->u.ci_wr.wr_sync = !!(file->f_flags & O_SYNC ||
file->f_flags & O_DIRECT ||
IS_SYNC(inode));
}
io->ci_lockreq = CILR_MANDATORY;
}
io->ci_noatime = file_is_noatime(file);
- if (ll_i2sbi(inode)->ll_flags & LL_SBI_PIO)
- io->ci_pio = !io->u.ci_rw.rw_append;
- else
- io->ci_pio = 0;
/* FLR: only use non-delay I/O for read as there is only one
* avaliable mirror for write. */
ll_io_set_mirror(io, file);
}
-static int ll_file_io_ptask(struct cfs_ptask *ptask)
+static void ll_heat_add(struct inode *inode, enum cl_io_type iot,
+ __u64 count)
{
- struct cl_io_pt *pt = ptask->pt_cbdata;
- struct file *file = pt->cip_file;
- struct lu_env *env;
- struct cl_io *io;
- loff_t pos = pt->cip_pos;
- int rc;
- __u16 refcheck;
- ENTRY;
-
- CDEBUG(D_VFSTRACE, "%s: %s range: [%llu, %llu)\n",
- file_dentry(file)->d_name.name,
- pt->cip_iot == CIT_READ ? "read" : "write",
- pos, pos + pt->cip_count);
-
- env = cl_env_get(&refcheck);
- if (IS_ERR(env))
- RETURN(PTR_ERR(env));
-
- io = vvp_env_thread_io(env);
- ll_io_init(io, file, pt->cip_iot);
- io->u.ci_rw.rw_iter = pt->cip_iter;
- io->u.ci_rw.rw_iocb = pt->cip_iocb;
- io->ci_pio = 0; /* It's already in parallel task */
-
- rc = cl_io_rw_init(env, io, pt->cip_iot, pos,
- pt->cip_count - pt->cip_result);
- if (!rc) {
- struct vvp_io *vio = vvp_env_io(env);
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ enum obd_heat_type sample_type;
+ enum obd_heat_type iobyte_type;
+ __u64 now = ktime_get_real_seconds();
- vio->vui_io_subtype = IO_NORMAL;
- vio->vui_fd = LUSTRE_FPRIVATE(file);
+ if (!ll_sbi_has_file_heat(sbi) ||
+ lli->lli_heat_flags & LU_HEAT_FLAG_OFF)
+ return;
- ll_cl_add(file, env, io, LCC_RW);
- rc = cl_io_loop(env, io);
- ll_cl_remove(file, env);
+ if (iot == CIT_READ) {
+ sample_type = OBD_HEAT_READSAMPLE;
+ iobyte_type = OBD_HEAT_READBYTE;
+ } else if (iot == CIT_WRITE) {
+ sample_type = OBD_HEAT_WRITESAMPLE;
+ iobyte_type = OBD_HEAT_WRITEBYTE;
} else {
- /* cl_io_rw_init() handled IO */
- rc = io->ci_result;
+ return;
}
- if (OBD_FAIL_CHECK_RESET(OBD_FAIL_LLITE_PTASK_IO_FAIL, 0)) {
- if (io->ci_nob > 0)
- io->ci_nob /= 2;
- rc = -EIO;
- }
-
- if (io->ci_nob > 0) {
- pt->cip_result += io->ci_nob;
- iov_iter_advance(&pt->cip_iter, io->ci_nob);
- pos += io->ci_nob;
- pt->cip_iocb.ki_pos = pos;
-#ifdef HAVE_KIOCB_KI_LEFT
- pt->cip_iocb.ki_left = pt->cip_count - pt->cip_result;
-#elif defined(HAVE_KI_NBYTES)
- pt->cip_iocb.ki_nbytes = pt->cip_count - pt->cip_result;
-#endif
- }
-
- cl_io_fini(env, io);
- cl_env_put(env, &refcheck);
-
- pt->cip_need_restart = io->ci_need_restart;
-
- CDEBUG(D_VFSTRACE, "%s: %s ret: %zd, rc: %d\n",
- file_dentry(file)->d_name.name,
- pt->cip_iot == CIT_READ ? "read" : "write",
- pt->cip_result, rc);
-
- RETURN(pt->cip_result > 0 ? 0 : rc);
+ spin_lock(&lli->lli_heat_lock);
+ obd_heat_add(&lli->lli_heat_instances[sample_type], now, 1,
+ sbi->ll_heat_decay_weight, sbi->ll_heat_period_second);
+ obd_heat_add(&lli->lli_heat_instances[iobyte_type], now, count,
+ sbi->ll_heat_decay_weight, sbi->ll_heat_period_second);
+ spin_unlock(&lli->lli_heat_lock);
}
static ssize_t
struct file *file, enum cl_io_type iot,
loff_t *ppos, size_t count)
{
- struct range_lock range;
struct vvp_io *vio = vvp_env_io(env);
struct inode *inode = file_inode(file);
struct ll_inode_info *lli = ll_i2info(inode);
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+ struct range_lock range;
struct cl_io *io;
- loff_t pos = *ppos;
ssize_t result = 0;
int rc = 0;
unsigned retried = 0;
ENTRY;
- CDEBUG(D_VFSTRACE, "%s: %s range: [%llu, %llu)\n",
+ CDEBUG(D_VFSTRACE, "%s: %s ppos: %llu, count: %zu\n",
file_dentry(file)->d_name.name,
- iot == CIT_READ ? "read" : "write", pos, pos + count);
+ iot == CIT_READ ? "read" : "write", *ppos, count);
restart:
io = vvp_env_thread_io(env);
ll_io_init(io, file, iot);
- if (args->via_io_subtype == IO_NORMAL) {
- io->u.ci_rw.rw_iter = *args->u.normal.via_iter;
- io->u.ci_rw.rw_iocb = *args->u.normal.via_iocb;
- }
- if (args->via_io_subtype != IO_NORMAL || restarted)
- io->ci_pio = 0;
io->ci_ndelay_tried = retried;
- if (cl_io_rw_init(env, io, iot, pos, count) == 0) {
+ if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
bool range_locked = false;
if (file->f_flags & O_APPEND)
range_lock_init(&range, 0, LUSTRE_EOF);
else
- range_lock_init(&range, pos, pos + count - 1);
+ range_lock_init(&range, *ppos, *ppos + count - 1);
vio->vui_fd = LUSTRE_FPRIVATE(file);
vio->vui_io_subtype = args->via_io_subtype;
switch (vio->vui_io_subtype) {
case IO_NORMAL:
+ vio->vui_iter = args->u.normal.via_iter;
+ vio->vui_iocb = args->u.normal.via_iocb;
/* Direct IO reads must also take range lock,
* or multiple reads will try to work on the same pages
* See LU-6227 for details. */
}
ll_cl_add(file, env, io, LCC_RW);
- if (io->ci_pio && iot == CIT_WRITE && !IS_NOSEC(inode) &&
- !lli->lli_inode_locked) {
- inode_lock(inode);
- lli->lli_inode_locked = 1;
- }
rc = cl_io_loop(env, io);
- if (lli->lli_inode_locked) {
- lli->lli_inode_locked = 0;
- inode_unlock(inode);
- }
ll_cl_remove(file, env);
if (range_locked) {
if (io->ci_nob > 0) {
result += io->ci_nob;
count -= io->ci_nob;
+ *ppos = io->u.ci_wr.wr.crw_pos; /* for splice */
- if (args->via_io_subtype == IO_NORMAL) {
- iov_iter_advance(args->u.normal.via_iter, io->ci_nob);
-
- /* CLIO is too complicated. See LU-11069. */
- if (cl_io_is_append(io))
- pos = io->u.ci_rw.rw_iocb.ki_pos;
- else
- pos += io->ci_nob;
-
- args->u.normal.via_iocb->ki_pos = pos;
-#ifdef HAVE_KIOCB_KI_LEFT
- args->u.normal.via_iocb->ki_left = count;
-#elif defined(HAVE_KI_NBYTES)
- args->u.normal.via_iocb->ki_nbytes = count;
-#endif
- } else {
- /* for splice */
- pos = io->u.ci_rw.rw_range.cir_pos;
- }
+ /* prepare IO restart */
+ if (count > 0 && args->via_io_subtype == IO_NORMAL)
+ args->u.normal.via_iter = vio->vui_iter;
}
out:
cl_io_fini(env, io);
if ((rc == 0 || rc == -ENODATA) && count > 0 && io->ci_need_restart) {
CDEBUG(D_VFSTRACE,
- "%s: restart %s range: [%llu, %llu) ret: %zd, rc: %d\n",
- file_dentry(file)->d_name.name,
- iot == CIT_READ ? "read" : "write",
- pos, pos + count, result, rc);
+ "%s: restart %s from %lld, count: %zu, ret: %zd, rc: %d\n",
+ file_dentry(file)->d_name.name,
+ iot == CIT_READ ? "read" : "write",
+ *ppos, count, result, rc);
/* preserve the tried count for FLR */
retried = io->ci_ndelay_tried;
restarted = true;
}
}
- CDEBUG(D_VFSTRACE, "%s: %s *ppos: %llu, pos: %llu, ret: %zd, rc: %d\n",
- file_dentry(file)->d_name.name,
- iot == CIT_READ ? "read" : "write", *ppos, pos, result, rc);
-
- *ppos = pos;
+ CDEBUG(D_VFSTRACE, "iot: %d, result: %zd\n", iot, result);
+ if (result > 0)
+ ll_heat_add(inode, iot, result);
RETURN(result > 0 ? result : rc);
}
if (result == -ENODATA)
result = 0;
- if (result > 0)
+ if (result > 0) {
+ ll_heat_add(file_inode(iocb->ki_filp), CIT_READ, result);
ll_stats_ops_tally(ll_i2sbi(file_inode(iocb->ki_filp)),
LPROC_LL_READ_BYTES, result);
+ }
return result;
}
ssize_t rc2;
__u16 refcheck;
+ ll_ras_enter(iocb->ki_filp);
+
result = ll_do_fast_read(iocb, to);
if (result < 0 || iov_iter_count(to) == 0)
GOTO(out, result);
static ssize_t ll_do_tiny_write(struct kiocb *iocb, struct iov_iter *iter)
{
ssize_t count = iov_iter_count(iter);
- struct file *file = iocb->ki_filp;
- struct inode *inode = file_inode(file);
+ struct file *file = iocb->ki_filp;
+ struct inode *inode = file_inode(file);
+ bool lock_inode = !IS_NOSEC(inode);
ssize_t result = 0;
ENTRY;
(iocb->ki_pos & (PAGE_SIZE-1)) + count > PAGE_SIZE)
RETURN(0);
+ if (unlikely(lock_inode))
+ inode_lock(inode);
result = __generic_file_write_iter(iocb, iter);
+ if (unlikely(lock_inode))
+ inode_unlock(inode);
+
/* If the page is not already dirty, ll_tiny_write_begin returns
* -ENODATA. We continue on to normal write.
*/
result = 0;
if (result > 0) {
+ ll_heat_add(inode, CIT_WRITE, result);
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_WRITE_BYTES,
result);
ll_file_set_flag(ll_i2info(inode), LLIF_DATA_MODIFIED);
__u16 refcheck;
ENTRY;
+ ll_ras_enter(in_file);
+
env = cl_env_get(&refcheck);
if (IS_ERR(env))
RETURN(PTR_ERR(env));
if (lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_V1) &&
lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_V3) &&
- lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_COMP_V1))
+ lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_COMP_V1) &&
+ lmm->lmm_magic != cpu_to_le32(LOV_MAGIC_FOREIGN))
GOTO(out, rc = -EPROTO);
/*
cpu_to_le32(LOV_MAGIC_COMP_V1)) {
lustre_swab_lov_comp_md_v1(
(struct lov_comp_md_v1 *)lmm);
+ } else if (lmm->lmm_magic ==
+ cpu_to_le32(LOV_MAGIC_FOREIGN)) {
+ struct lov_foreign_md *lfm;
+
+ lfm = (struct lov_foreign_md *)lmm;
+ __swab32s(&lfm->lfm_magic);
+ __swab32s(&lfm->lfm_length);
+ __swab32s(&lfm->lfm_type);
+ __swab32s(&lfm->lfm_flags);
}
}
ENTRY;
CDEBUG(D_INODE, "%s: Releasing file "DFID".\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
+ ll_i2sbi(inode)->ll_fsname,
PFID(&ll_i2info(inode)->lli_fid));
och = ll_lease_open(inode, NULL, FMODE_WRITE, MDS_OPEN_RELEASE);
int ll_hsm_state_set(struct inode *inode, struct hsm_state_set *hss)
{
- struct md_op_data *op_data;
- int rc;
+ struct obd_export *exp = ll_i2mdexp(inode);
+ struct md_op_data *op_data;
+ int rc;
ENTRY;
/* Detect out-of range masks */
!cfs_capable(CFS_CAP_SYS_ADMIN))
RETURN(-EPERM);
- /* Detect out-of range archive id */
- if ((hss->hss_valid & HSS_ARCHIVE_ID) &&
- (hss->hss_archive_id > LL_HSM_MAX_ARCHIVE))
- RETURN(-EINVAL);
+ if (!exp_connect_archive_id_array(exp)) {
+ /* Detect out-of range archive id */
+ if ((hss->hss_valid & HSS_ARCHIVE_ID) &&
+ (hss->hss_archive_id > LL_HSM_ORIGIN_MAX_ARCHIVE))
+ RETURN(-EINVAL);
+ }
op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
LUSTRE_OPC_ANY, hss);
if (IS_ERR(op_data))
RETURN(PTR_ERR(op_data));
- rc = obd_iocontrol(LL_IOC_HSM_STATE_SET, ll_i2mdexp(inode),
- sizeof(*op_data), op_data, NULL);
+ rc = obd_iocontrol(LL_IOC_HSM_STATE_SET, exp, sizeof(*op_data),
+ op_data, NULL);
ll_finish_md_op_data(op_data);
static int ll_ladvise_sanity(struct inode *inode,
struct llapi_lu_ladvise *ladvise)
{
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
enum lu_ladvise_type advice = ladvise->lla_advice;
/* Note the peradvice flags is a 32 bit field, so per advice flags must
* be in the first 32 bits of enum ladvise_flags */
rc = -EINVAL;
CDEBUG(D_VFSTRACE, "%s: advice with value '%d' not recognized,"
"last supported advice is %s (value '%d'): rc = %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0), advice,
+ sbi->ll_fsname, advice,
ladvise_names[LU_LADVISE_MAX-1], LU_LADVISE_MAX-1, rc);
GOTO(out, rc);
}
if (flags & ~LF_LOCKNOEXPAND_MASK) {
rc = -EINVAL;
CDEBUG(D_VFSTRACE, "%s: Invalid flags (%x) for %s: "
- "rc = %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0), flags,
+ "rc = %d\n", sbi->ll_fsname, flags,
ladvise_names[advice], rc);
GOTO(out, rc);
}
ladvise->lla_lockahead_mode == 0) {
rc = -EINVAL;
CDEBUG(D_VFSTRACE, "%s: Invalid mode (%d) for %s: "
- "rc = %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
+ "rc = %d\n", sbi->ll_fsname,
ladvise->lla_lockahead_mode,
ladvise_names[advice], rc);
GOTO(out, rc);
if (flags & ~LF_DEFAULT_MASK) {
rc = -EINVAL;
CDEBUG(D_VFSTRACE, "%s: Invalid flags (%x) for %s: "
- "rc = %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0), flags,
+ "rc = %d\n", sbi->ll_fsname, flags,
ladvise_names[advice], rc);
GOTO(out, rc);
}
if (ladvise->lla_start >= ladvise->lla_end) {
rc = -EINVAL;
CDEBUG(D_VFSTRACE, "%s: Invalid range (%llu to %llu) "
- "for %s: rc = %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
+ "for %s: rc = %d\n", sbi->ll_fsname,
ladvise->lla_start, ladvise->lla_end,
ladvise_names[advice], rc);
GOTO(out, rc);
RETURN(rc);
}
+static void ll_heat_get(struct inode *inode, struct lu_heat *heat)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ __u64 now = ktime_get_real_seconds();
+ int i;
+
+ spin_lock(&lli->lli_heat_lock);
+ heat->lh_flags = lli->lli_heat_flags;
+ for (i = 0; i < heat->lh_count; i++)
+ heat->lh_heat[i] = obd_heat_get(&lli->lli_heat_instances[i],
+ now, sbi->ll_heat_decay_weight,
+ sbi->ll_heat_period_second);
+ spin_unlock(&lli->lli_heat_lock);
+}
+
+static int ll_heat_set(struct inode *inode, enum lu_heat_flag flags)
+{
+ struct ll_inode_info *lli = ll_i2info(inode);
+ int rc = 0;
+
+ spin_lock(&lli->lli_heat_lock);
+ if (flags & LU_HEAT_FLAG_CLEAR)
+ obd_heat_clear(lli->lli_heat_instances, OBD_HEAT_COUNT);
+
+ if (flags & LU_HEAT_FLAG_OFF)
+ lli->lli_heat_flags |= LU_HEAT_FLAG_OFF;
+ else
+ lli->lli_heat_flags &= ~LU_HEAT_FLAG_OFF;
+
+ spin_unlock(&lli->lli_heat_lock);
+
+ RETURN(rc);
+}
+
static long
ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
RETURN(ll_ioctl_fssetxattr(inode, cmd, arg));
case BLKSSZGET:
RETURN(put_user(PAGE_SIZE, (int __user *)arg));
+ case LL_IOC_HEAT_GET: {
+ struct lu_heat uheat;
+ struct lu_heat *heat;
+ int size;
+
+ if (copy_from_user(&uheat, (void __user *)arg, sizeof(uheat)))
+ RETURN(-EFAULT);
+
+ if (uheat.lh_count > OBD_HEAT_COUNT)
+ uheat.lh_count = OBD_HEAT_COUNT;
+
+ size = offsetof(typeof(uheat), lh_heat[uheat.lh_count]);
+ OBD_ALLOC(heat, size);
+ if (heat == NULL)
+ RETURN(-ENOMEM);
+
+ heat->lh_count = uheat.lh_count;
+ ll_heat_get(inode, heat);
+ rc = copy_to_user((char __user *)arg, heat, size);
+ OBD_FREE(heat, size);
+ RETURN(rc ? -EFAULT : 0);
+ }
+ case LL_IOC_HEAT_SET: {
+ __u64 flags;
+
+ if (copy_from_user(&flags, (void __user *)arg, sizeof(flags)))
+ RETURN(-EFAULT);
+
+ rc = ll_heat_set(inode, flags);
+ RETURN(rc);
+ }
default:
RETURN(obd_iocontrol(cmd, ll_i2dtexp(inode), 0, NULL,
(void __user *)arg));
int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{
struct dentry *dentry = file_dentry(file);
- bool lock_inode;
#elif defined(HAVE_FILE_FSYNC_2ARGS)
int ll_fsync(struct file *file, int datasync)
{
#ifdef HAVE_FILE_FSYNC_4ARGS
rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
- lock_inode = !lli->lli_inode_locked;
- if (lock_inode)
- inode_lock(inode);
+ inode_lock(inode);
#else
/* fsync's caller has already called _fdata{sync,write}, we want
* that IO to finish before calling the osc and mdc sync methods */
}
#ifdef HAVE_FILE_FSYNC_4ARGS
- if (lock_inode)
- inode_unlock(inode);
+ inode_unlock(inode);
#endif
RETURN(rc);
}
if (le32_to_cpu(lum->lum_stripe_count) > 1 ||
ll_i2info(child_inode)->lli_lsm_md) {
CERROR("%s: MDT doesn't support stripe directory "
- "migration!\n",
- ll_get_fsname(parent->i_sb, NULL, 0));
+ "migration!\n", ll_i2sbi(parent)->ll_fsname);
GOTO(out_iput, rc = -EOPNOTSUPP);
}
}
op_data->op_fid3 = *ll_inode2fid(child_inode);
if (!fid_is_sane(&op_data->op_fid3)) {
CERROR("%s: migrate %s, but FID "DFID" is insane\n",
- ll_get_fsname(parent->i_sb, NULL, 0), name,
+ ll_i2sbi(parent)->ll_fsname, name,
PFID(&op_data->op_fid3));
GOTO(out_unlock, rc = -EINVAL);
}
if (rc == 0) {
LASSERT(request != NULL);
ll_update_times(request, parent);
+ }
+ if (rc == 0 || rc == -EAGAIN) {
body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
LASSERT(body != NULL);
request = NULL;
}
- /* Try again if the file layout has changed. */
+ /* Try again if the lease has cancelled. */
if (rc == -EAGAIN && S_ISREG(child_inode->i_mode))
goto again;
} else if (rc != 0) {
CDEBUG_LIMIT((rc == -EACCES || rc == -EIDRM) ? D_INFO : D_ERROR,
"%s: revalidate FID "DFID" error: rc = %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
+ ll_i2sbi(inode)->ll_fsname,
PFID(ll_inode2fid(inode)), rc);
}
int rc;
LASSERT(lli->lli_lsm_md != NULL);
+
+ /* foreign dir is not striped dir */
+ if (lli->lli_lsm_md->lsm_md_magic == LMV_MAGIC_FOREIGN)
+ RETURN(0);
+
down_read(&lli->lli_lsm_sem);
rc = md_merge_attr(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
&attr, ll_md_blocking_ast);
RETURN(rc);
}
- LTIME_S(inode->i_atime) = lli->lli_atime;
- LTIME_S(inode->i_mtime) = lli->lli_mtime;
- LTIME_S(inode->i_ctime) = lli->lli_ctime;
+ inode->i_atime.tv_sec = lli->lli_atime;
+ inode->i_mtime.tv_sec = lli->lli_mtime;
+ inode->i_ctime.tv_sec = lli->lli_ctime;
}
OBD_FAIL_TIMEOUT(OBD_FAIL_GETATTR_DELAY, 30);
rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), OBD_MD_FLXATTR,
XATTR_NAME_LOV, lmmsize, &req);
- if (rc < 0)
- RETURN(rc);
+ if (rc < 0) {
+ if (rc == -ENODATA)
+ GOTO(out, rc = 0); /* empty layout */
+ else
+ RETURN(rc);
+ }
lmmsize = rc;
rc = 0;
/* wait for IO to complete if it's still being used. */
if (wait_layout) {
CDEBUG(D_INODE, "%s: "DFID"(%p) wait for layout reconf\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
- PFID(&lli->lli_fid), inode);
+ sbi->ll_fsname, PFID(&lli->lli_fid), inode);
memset(&conf, 0, sizeof conf);
conf.coc_opc = OBJECT_CONF_WAIT;
rc = -EAGAIN;
CDEBUG(D_INODE, "%s file="DFID" waiting layout return: %d\n",
- ll_get_fsname(inode->i_sb, NULL, 0),
- PFID(&lli->lli_fid), rc);
+ sbi->ll_fsname, PFID(&lli->lli_fid), rc);
}
RETURN(rc);
}
it.it_flags = FMODE_WRITE;
LDLM_DEBUG_NOLOCK("%s: requeue layout lock for file "DFID"(%p)",
- ll_get_fsname(inode->i_sb, NULL, 0),
- PFID(&lli->lli_fid), inode);
+ sbi->ll_fsname, PFID(&lli->lli_fid), inode);
rc = md_intent_lock(sbi->ll_md_exp, op_data, &it, &req,
&ll_md_blocking_ast, 0);