CDEBUG(D_VFSTRACE, "lock: %i [%lu, %lu]\n", mode, start, end);
memset(&cio->cui_link, 0, sizeof cio->cui_link);
- descr->cld_mode = mode;
+
+ if (cio->cui_fd && (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
+ descr->cld_mode = CLM_GROUP;
+ descr->cld_gid = cio->cui_fd->fd_grouplock.cg_gid;
+ } else {
+ descr->cld_mode = mode;
+ }
descr->cld_obj = obj;
descr->cld_start = start;
descr->cld_end = end;
ENTRY;
/* clear group lock, if present */
- if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
- struct lov_stripe_md *lsm = llu_i2info(inode)->lli_smd;
- fd->fd_flags &= ~(LL_FILE_GROUP_LOCKED|LL_FILE_IGNORE_LOCK);
- rc = llu_extent_unlock(fd, inode, lsm, LCK_GROUP,
- &fd->fd_cwlockh);
- }
+ if (fd->fd_flags & LL_FILE_GROUP_LOCKED)
+ llu_put_grouplock(inode, fd->fd_grouplock.cg_gid);
op_data.op_attr.ia_valid = ATTR_MODE | ATTR_ATIME_SET |
ATTR_MTIME_SET | ATTR_CTIME_SET;
struct ll_file_data {
struct obd_client_handle fd_mds_och;
__u32 fd_flags;
- struct lustre_handle fd_cwlockh;
- unsigned long fd_gid;
+ struct ccc_grouplock fd_grouplock;
};
struct llu_sb_info {
int llu_md_setattr(struct inode *inode, struct md_op_data *op_data,
struct md_open_data **mod);
int llu_setattr_raw(struct inode *inode, struct iattr *attr);
+int llu_put_grouplock(struct inode *inode, unsigned long arg);
extern struct fssw_ops llu_fssw_ops;
{
struct llu_inode_info *lli = llu_i2info(inode);
struct ll_file_data *fd = lli->lli_file_data;
- ldlm_policy_data_t policy = { .l_extent = { .start = 0,
- .end = OBD_OBJECT_EOF}};
- struct lustre_handle lockh = { 0 };
- struct lov_stripe_md *lsm = lli->lli_smd;
- ldlm_error_t err;
- int flags = 0;
+ int rc;
+ struct ccc_grouplock grouplock;
ENTRY;
+ if (fd->fd_flags & LL_FILE_IGNORE_LOCK) {
+ RETURN(-ENOTSUPP);
+ }
if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
RETURN(-EINVAL);
}
+ LASSERT(fd->fd_grouplock.cg_lock == NULL);
- policy.l_extent.gid = arg;
- if (lli->lli_open_flags & O_NONBLOCK)
- flags = LDLM_FL_BLOCK_NOWAIT;
+ rc = cl_get_grouplock(cl_i2info(inode)->lli_clob,
+ arg, (lli->lli_open_flags & O_NONBLOCK),
+ &grouplock);
- err = llu_extent_lock(fd, inode, lsm, LCK_GROUP, &policy, &lockh,
- flags);
- if (err)
- RETURN(err);
+ if (rc)
+ RETURN(rc);
- fd->fd_flags |= LL_FILE_GROUP_LOCKED|LL_FILE_IGNORE_LOCK;
- fd->fd_gid = arg;
- memcpy(&fd->fd_cwlockh, &lockh, sizeof(lockh));
+ fd->fd_flags |= LL_FILE_GROUP_LOCKED;
+ fd->fd_grouplock = grouplock;
RETURN(0);
}
-static int llu_put_grouplock(struct inode *inode, unsigned long arg)
+int llu_put_grouplock(struct inode *inode, unsigned long arg)
{
struct llu_inode_info *lli = llu_i2info(inode);
struct ll_file_data *fd = lli->lli_file_data;
- struct lov_stripe_md *lsm = lli->lli_smd;
- ldlm_error_t err;
+ struct ccc_grouplock grouplock;
ENTRY;
if (!(fd->fd_flags & LL_FILE_GROUP_LOCKED))
RETURN(-EINVAL);
- if (fd->fd_gid != arg)
- RETURN(-EINVAL);
+ LASSERT(fd->fd_grouplock.cg_lock != NULL);
- fd->fd_flags &= ~(LL_FILE_GROUP_LOCKED|LL_FILE_IGNORE_LOCK);
+ if (fd->fd_grouplock.cg_gid != arg)
+ RETURN(-EINVAL);
- err = llu_extent_unlock(fd, inode, lsm, LCK_GROUP, &fd->fd_cwlockh);
- if (err)
- RETURN(err);
+ grouplock = fd->fd_grouplock;
+ memset(&fd->fd_grouplock, 0, sizeof(fd->fd_grouplock));
+ fd->fd_flags &= ~LL_FILE_GROUP_LOCKED;
- fd->fd_gid = 0;
- memset(&fd->fd_cwlockh, 0, sizeof(fd->fd_cwlockh));
+ cl_put_grouplock(&grouplock);
RETURN(0);
}
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);
vio->cui_io_subtype = args->via_io_subtype;
switch (vio->cui_io_subtype) {
#ifndef HAVE_FILE_WRITEV
cio->cui_iocb = args->u.normal.via_iocb;
#endif
+ if ((iot == CIT_WRITE) &&
+ !(cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
+ down(&lli->lli_write_sem);
+ write_sem_locked = 1;
+ }
break;
case IO_SENDFILE:
vio->u.sendfile.cui_actor = args->u.sendfile.via_actor;
CERROR("Unknow IO type - %u\n", vio->cui_io_subtype);
LBUG();
}
- cio->cui_fd = LUSTRE_FPRIVATE(file);
result = cl_io_loop(env, io);
+ if (write_sem_locked)
+ up(&lli->lli_write_sem);
} else {
/* cl_io_rw_init() handled IO */
result = io->ci_result;
spin_lock(&lli->lli_lock);
if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
- CERROR("group lock already existed with gid %lu\n",
+ CWARN("group lock already existed with gid %lu\n",
fd->fd_grouplock.cg_gid);
spin_unlock(&lli->lli_lock);
RETURN(-EINVAL);
spin_lock(&lli->lli_lock);
if (!(fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
spin_unlock(&lli->lli_lock);
- CERROR("no group lock held\n");
+ CWARN("no group lock held\n");
RETURN(-EINVAL);
}
LASSERT(fd->fd_grouplock.cg_lock != NULL);
if (fd->fd_grouplock.cg_gid != arg) {
- CERROR("group lock %lu doesn't match current id %lu\n",
+ CWARN("group lock %lu doesn't match current id %lu\n",
arg, fd->fd_grouplock.cg_gid);
spin_unlock(&lli->lli_lock);
RETURN(-EINVAL);
}
grouplock = fd->fd_grouplock;
- fd->fd_grouplock.cg_env = NULL;
- fd->fd_grouplock.cg_lock = NULL;
- fd->fd_grouplock.cg_gid = 0;
+ memset(&fd->fd_grouplock, 0, sizeof(fd->fd_grouplock));
fd->fd_flags &= ~LL_FILE_GROUP_LOCKED;
spin_unlock(&lli->lli_lock);
struct cl_object *obj = io->ci_obj;
CLOBINVRNT(env, obj, ccc_object_invariant(obj));
- if (io->ci_type == CIT_WRITE)
- up(&ll_i2info(ccc_object_inode(obj))->lli_write_sem);
- else {
+ if (io->ci_type == CIT_READ) {
struct vvp_io *vio = cl2vvp_io(env, ios);
struct ccc_io *cio = cl2ccc_io(env, ios);
count = io->u.ci_rw.crw_count;
op = io->ci_type == CIT_READ ?
LPROC_LL_READ_BYTES : LPROC_LL_WRITE_BYTES;
- if (io->ci_type == CIT_WRITE)
- down(&ll_i2info(inode)->lli_write_sem);
/* "If nbyte is 0, read() will return 0 and have no other
* results." -- Single Unix Spec */
if (count == 0)
need->cld_start = need->cld_end = page->cp_index;
spin_lock(&head->coh_lock_guard);
+ /* It is fine to match any group lock since there could be only one
+ * with a uniq gid and it conflicts with all other lock modes too */
list_for_each_entry(scan, &head->coh_locks, cll_linkage) {
if (scan != except &&
- cl_lock_ext_match(&scan->cll_descr, need) &&
+ (scan->cll_descr.cld_mode == CLM_GROUP ||
+ cl_lock_ext_match(&scan->cll_descr, need)) &&
scan->cll_state >= CLS_HELD &&
scan->cll_state < CLS_FREEING &&
/*
MPI_Barrier(MPI_COMM_WORLD);
if (verbose > 0 && rank == 0) {
gettimeofday(&t2, NULL);
- elapsed = (t2.tv_sec + ((float)t2.tv_usec/1000000))
- - (t1.tv_sec + ((float)t1.tv_usec/1000000));
+
+ elapsed = t2.tv_sec - t1.tv_sec +
+ (float)(t2.tv_usec-t1.tv_usec)/1000000;
if (elapsed >= 60) {
printf("%s:\tFinished %-15s(%.2f min)\n",
timestamp(), str, elapsed / 60);
if (size < MIN_GLHOST) {
fprintf(stderr, "Error: "
- "should be at least four tasks to run the test!\n");
+ "%d tasks run, but should be at least %d tasks to run "
+ "the test!\n", size, MIN_GLHOST);
MPI_Abort(MPI_COMM_WORLD, 2);
}