CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), flags %o\n", inode->i_ino,
inode->i_generation, inode, file->f_flags);
-#ifdef HAVE_VFS_INTENT_PATCHES
- it = file->f_it;
-#else
it = file->private_data; /* XXX: compat macro */
file->private_data = NULL; /* prevent ll_local_open assertion */
-#endif
fd = ll_file_data_get();
if (fd == NULL)
* dentry_open after call to open_namei that checks permissions.
* Only nfsd_open call dentry_open directly without checking
* permissions and because of that this code below is safe. */
- if (oit.it_flags & FMODE_WRITE)
+ if (oit.it_flags & (FMODE_WRITE | FMODE_READ))
oit.it_flags |= MDS_OPEN_OWNEROVERRIDE;
/* We do not want O_EXCL here, presumably we opened the file
struct vvp_io_args *args, struct file *file,
enum cl_io_type iot, loff_t *ppos, size_t count)
{
- struct cl_io *io;
- ssize_t result;
+ struct ll_inode_info *lli = ll_i2info(file->f_dentry->d_inode);
+ struct cl_io *io;
+ ssize_t result;
ENTRY;
io = &ccc_env_info(env)->cti_io;
if (cl_io_rw_init(env, io, iot, *ppos, count) == 0) {
struct vvp_io *vio = vvp_env_io(env);
struct ccc_io *cio = ccc_env_io(env);
- struct ll_inode_info *lli = ll_i2info(file->f_dentry->d_inode);
int write_sem_locked = 0;
cio->cui_fd = LUSTRE_FPRIVATE(file);
if(cfs_down_interruptible(&lli->lli_write_sem))
GOTO(out, result = -ERESTARTSYS);
write_sem_locked = 1;
+ } else if (iot == CIT_READ) {
+ cfs_down_read(&lli->lli_trunc_sem);
}
break;
case IO_SENDFILE:
result = cl_io_loop(env, io);
if (write_sem_locked)
cfs_up(&lli->lli_write_sem);
+ else if (args->via_io_subtype == IO_NORMAL && iot == CIT_READ)
+ cfs_up_read(&lli->lli_trunc_sem);
} else {
/* cl_io_rw_init() handled IO */
result = io->ci_result;
GOTO(out, result);
out:
cl_io_fini(env, io);
+ if (iot == CIT_WRITE)
+ lli->lli_write_rc = result < 0 ? : 0;
return result;
}
lsm_size = sizeof(*lsm) + (sizeof(struct lov_oinfo) *
(lsm->lsm_stripe_count));
- OBD_ALLOC(lsm2, lsm_size);
+ OBD_ALLOC_LARGE(lsm2, lsm_size);
if (lsm2 == NULL)
GOTO(out, rc = -ENOMEM);
memcpy(lsm2, lsm, lsm_size);
rc = obd_create(exp, oa, &lsm2, &oti);
- OBD_FREE(lsm2, lsm_size);
+ OBD_FREE_LARGE(lsm2, lsm_size);
GOTO(out, rc);
out:
ll_inode_size_unlock(inode, 0);
if (!cfs_capable(CFS_CAP_SYS_ADMIN))
RETURN(-EPERM);
- OBD_ALLOC(lump, lum_size);
+ OBD_ALLOC_LARGE(lump, lum_size);
if (lump == NULL) {
RETURN(-ENOMEM);
}
if (cfs_copy_from_user(lump, (struct lov_user_md *)arg, lum_size)) {
- OBD_FREE(lump, lum_size);
+ OBD_FREE_LARGE(lump, lum_size);
RETURN(-EFAULT);
}
rc = ll_lov_setstripe_ea_info(inode, file, flags, lump, lum_size);
- OBD_FREE(lump, lum_size);
+ OBD_FREE_LARGE(lump, lum_size);
RETURN(rc);
}
num_bytes = sizeof(*fiemap_s) + (extent_count *
sizeof(struct ll_fiemap_extent));
- OBD_VMALLOC(fiemap_s, num_bytes);
+ OBD_ALLOC_LARGE(fiemap_s, num_bytes);
if (fiemap_s == NULL)
RETURN(-ENOMEM);
rc = -EFAULT;
error:
- OBD_VFREE(fiemap_s, num_bytes);
+ OBD_FREE_LARGE(fiemap_s, num_bytes);
RETURN(rc);
}
+#ifdef HAVE_UNLOCKED_IOCTL
+long ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct inode *inode = file->f_dentry->d_inode;
+#else
int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
+#endif
struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
int flags;
ENTRY;
struct lov_stripe_md *lsm = lli->lli_smd;
int rc, err;
+ /* the application should know write failure already. */
+ if (lli->lli_write_rc)
+ return 0;
+
/* catch async errors that were recorded back when async writeback
* failed for pages in this mapping. */
rc = lli->lli_async_rc;
ptlrpc_req_finished(req);
if (data && lsm) {
- struct obdo *oa;
+ struct obd_info *oinfo;
- OBDO_ALLOC(oa);
- if (!oa)
+ OBD_ALLOC_PTR(oinfo);
+ if (!oinfo)
RETURN(rc ? rc : -ENOMEM);
-
- oa->o_id = lsm->lsm_object_id;
- oa->o_seq = lsm->lsm_object_seq;
- oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
- obdo_from_inode(oa, inode, &ll_i2info(inode)->lli_fid,
+ OBDO_ALLOC(oinfo->oi_oa);
+ if (!oinfo->oi_oa) {
+ OBD_FREE_PTR(oinfo);
+ RETURN(rc ? rc : -ENOMEM);
+ }
+ oinfo->oi_oa->o_id = lsm->lsm_object_id;
+ oinfo->oi_oa->o_seq = lsm->lsm_object_seq;
+ oinfo->oi_oa->o_valid = OBD_MD_FLID | OBD_MD_FLGROUP;
+ obdo_from_inode(oinfo->oi_oa, inode, &ll_i2info(inode)->lli_fid,
OBD_MD_FLTYPE | OBD_MD_FLATIME |
OBD_MD_FLMTIME | OBD_MD_FLCTIME |
OBD_MD_FLGROUP);
-
- oc = ll_osscapa_get(inode, CAPA_OPC_OSS_WRITE);
- err = obd_sync(ll_i2sbi(inode)->ll_dt_exp, oa, lsm,
- 0, OBD_OBJECT_EOF, oc);
- capa_put(oc);
+ oinfo->oi_md = lsm;
+ oinfo->oi_capa = ll_osscapa_get(inode, CAPA_OPC_OSS_WRITE);
+ err = obd_sync_rqset(ll_i2sbi(inode)->ll_dt_exp, oinfo, 0,
+ OBD_OBJECT_EOF);
+ capa_put(oinfo->oi_capa);
if (!rc)
rc = err;
- OBDO_FREE(oa);
+ OBDO_FREE(oinfo->oi_oa);
+ OBD_FREE_PTR(oinfo);
+ lli->lli_write_rc = err < 0 ? : 0;
}
RETURN(rc);
.ei_cbdata = file_lock };
struct md_op_data *op_data;
struct lustre_handle lockh = {0};
- ldlm_policy_data_t flock;
+ ldlm_policy_data_t flock = {{0}};
int flags = 0;
int rc;
ENTRY;
if (file_lock->fl_flags & FL_FLOCK) {
LASSERT((cmd == F_SETLKW) || (cmd == F_SETLK));
- /* set missing params for flock() calls */
- file_lock->fl_end = OFFSET_MAX;
- file_lock->fl_pid = current->tgid;
+ /* flocks are whole-file locks */
+ flock.l_flock.end = OFFSET_MAX;
+ /* For flocks owner is determined by the local file desctiptor*/
+ flock.l_flock.owner = (unsigned long)file_lock->fl_file;
+ } else if (file_lock->fl_flags & FL_POSIX) {
+ flock.l_flock.owner = (unsigned long)file_lock->fl_owner;
+ flock.l_flock.start = file_lock->fl_start;
+ flock.l_flock.end = file_lock->fl_end;
+ } else {
+ RETURN(-EINVAL);
}
flock.l_flock.pid = file_lock->fl_pid;
- flock.l_flock.start = file_lock->fl_start;
- flock.l_flock.end = file_lock->fl_end;
switch (file_lock->fl_type) {
case F_RDLCK:
exp = ll_i2mdexp(inode);
+ /* XXX: Enable OBD_CONNECT_ATTRFID to reduce unnecessary getattr RPC.
+ * But under CMD case, it caused some lock issues, should be fixed
+ * with new CMD ibits lock. See bug 12718 */
if (exp->exp_connect_flags & OBD_CONNECT_ATTRFID) {
struct lookup_intent oit = { .it_op = IT_GETATTR };
struct md_op_data *op_data;
+ if (ibits == MDS_INODELOCK_LOOKUP)
+ oit.it_op = IT_LOOKUP;
+
/* Call getattr by fid, so do not provide name at all. */
op_data = ll_prep_md_op_data(NULL, dentry->d_parent->d_inode,
dentry->d_inode, NULL, 0, 0,
return rc;
}
-int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it)
+int ll_inode_revalidate_it(struct dentry *dentry, struct lookup_intent *it,
+ __u64 ibits)
{
struct inode *inode = dentry->d_inode;
int rc;
ENTRY;
- rc = __ll_inode_revalidate_it(dentry, it, MDS_INODELOCK_UPDATE |
- MDS_INODELOCK_LOOKUP);
+ rc = __ll_inode_revalidate_it(dentry, it, ibits);
/* if object not yet allocated, don't validate size */
if (rc == 0 && ll_i2info(dentry->d_inode)->lli_smd == NULL) {
struct ll_inode_info *lli = ll_i2info(inode);
int res = 0;
- res = ll_inode_revalidate_it(de, it);
+ res = ll_inode_revalidate_it(de, it, MDS_INODELOCK_UPDATE |
+ MDS_INODELOCK_LOOKUP);
ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_GETATTR, 1);
if (res)
num_bytes = sizeof(*fiemap) + (extent_count *
sizeof(struct ll_fiemap_extent));
- OBD_VMALLOC(fiemap, num_bytes);
+ OBD_ALLOC_LARGE(fiemap, num_bytes);
if (fiemap == NULL)
RETURN(-ENOMEM);
memcpy(fieinfo->fi_extents_start, &fiemap->fm_extents[0],
fiemap->fm_mapped_extents * sizeof(struct ll_fiemap_extent));
- OBD_VFREE(fiemap, num_bytes);
+ OBD_FREE_LARGE(fiemap, num_bytes);
return rc;
}
#endif
.READ_METHOD = READ_FUNCTION,
.write = ll_file_write,
.WRITE_METHOD = WRITE_FUNCTION,
+#ifdef HAVE_UNLOCKED_IOCTL
+ .unlocked_ioctl = ll_file_ioctl,
+#else
.ioctl = ll_file_ioctl,
+#endif
.open = ll_file_open,
.release = ll_file_release,
.mmap = ll_file_mmap,
.READ_METHOD = READ_FUNCTION,
.write = ll_file_write,
.WRITE_METHOD = WRITE_FUNCTION,
+#ifdef HAVE_UNLOCKED_IOCTL
+ .unlocked_ioctl = ll_file_ioctl,
+#else
.ioctl = ll_file_ioctl,
+#endif
.open = ll_file_open,
.release = ll_file_release,
.mmap = ll_file_mmap,
.READ_METHOD = READ_FUNCTION,
.write = ll_file_write,
.WRITE_METHOD = WRITE_FUNCTION,
+#ifdef HAVE_UNLOCKED_IOCTL
+ .unlocked_ioctl = ll_file_ioctl,
+#else
.ioctl = ll_file_ioctl,
+#endif
.open = ll_file_open,
.release = ll_file_release,
.mmap = ll_file_mmap,
};
struct inode_operations ll_file_inode_operations = {
-#ifdef HAVE_VFS_INTENT_PATCHES
- .setattr_raw = ll_setattr_raw,
-#endif
.setattr = ll_setattr,
.truncate = ll_truncate,
.getattr = ll_getattr,