RETURN(rc);
}
-
static int
ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
{
RETURN(-EINVAL);
}
- if (ll_file_nolock(file))
- RETURN(-EOPNOTSUPP);
-retry:
- if (file->f_flags & O_NONBLOCK) {
- if (!mutex_trylock(&lli->lli_group_mutex))
- RETURN(-EAGAIN);
- } else
- mutex_lock(&lli->lli_group_mutex);
+ if (ll_file_nolock(file))
+ RETURN(-EOPNOTSUPP);
+ read_lock(&lli->lli_lock);
if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
CWARN("group lock already existed with gid %lu\n",
fd->fd_grouplock.lg_gid);
- GOTO(out, rc = -EINVAL);
- }
- if (arg != lli->lli_group_gid && lli->lli_group_users != 0) {
- if (file->f_flags & O_NONBLOCK)
- GOTO(out, rc = -EAGAIN);
- mutex_unlock(&lli->lli_group_mutex);
- wait_var_event(&lli->lli_group_users, !lli->lli_group_users);
- GOTO(retry, rc = 0);
+ read_unlock(&lli->lli_lock);
+ RETURN(-EINVAL);
}
LASSERT(fd->fd_grouplock.lg_lock == NULL);
+ read_unlock(&lli->lli_lock);
/**
* XXX: group lock needs to protect all OST objects while PFL
env = cl_env_get(&refcheck);
if (IS_ERR(env))
- GOTO(out, rc = PTR_ERR(env));
+ RETURN(PTR_ERR(env));
rc = cl_object_layout_get(env, obj, &cl);
if (rc >= 0 && cl.cl_is_composite)
cl_env_put(env, &refcheck);
if (rc < 0)
- GOTO(out, rc);
+ RETURN(rc);
}
rc = cl_get_grouplock(ll_i2info(inode)->lli_clob,
arg, (file->f_flags & O_NONBLOCK), &grouplock);
-
if (rc)
- GOTO(out, rc);
+ RETURN(rc);
+
+ write_lock(&lli->lli_lock);
+ if (fd->fd_flags & LL_FILE_GROUP_LOCKED) {
+ write_unlock(&lli->lli_lock);
+ CERROR("another thread just won the race\n");
+ cl_put_grouplock(&grouplock);
+ RETURN(-EINVAL);
+ }
fd->fd_flags |= LL_FILE_GROUP_LOCKED;
fd->fd_grouplock = grouplock;
- if (lli->lli_group_users == 0)
- lli->lli_group_gid = grouplock.lg_gid;
- lli->lli_group_users++;
+ write_unlock(&lli->lli_lock);
CDEBUG(D_INFO, "group lock %lu obtained\n", arg);
-out:
- mutex_unlock(&lli->lli_group_mutex);
-
- RETURN(rc);
+ RETURN(0);
}
static int ll_put_grouplock(struct inode *inode, struct file *file,
struct ll_inode_info *lli = ll_i2info(inode);
struct ll_file_data *fd = file->private_data;
struct ll_grouplock grouplock;
- int rc;
ENTRY;
- mutex_lock(&lli->lli_group_mutex);
+ write_lock(&lli->lli_lock);
if (!(fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
- CWARN("no group lock held\n");
- GOTO(out, rc = -EINVAL);
- }
+ write_unlock(&lli->lli_lock);
+ CWARN("no group lock held\n");
+ RETURN(-EINVAL);
+ }
LASSERT(fd->fd_grouplock.lg_lock != NULL);
if (fd->fd_grouplock.lg_gid != arg) {
CWARN("group lock %lu doesn't match current id %lu\n",
arg, fd->fd_grouplock.lg_gid);
- GOTO(out, rc = -EINVAL);
+ write_unlock(&lli->lli_lock);
+ RETURN(-EINVAL);
}
grouplock = fd->fd_grouplock;
memset(&fd->fd_grouplock, 0, sizeof(fd->fd_grouplock));
fd->fd_flags &= ~LL_FILE_GROUP_LOCKED;
+ write_unlock(&lli->lli_lock);
cl_put_grouplock(&grouplock);
-
- lli->lli_group_users--;
- if (lli->lli_group_users == 0) {
- lli->lli_group_gid = 0;
- wake_up_var(&lli->lli_group_users);
- }
CDEBUG(D_INFO, "group lock %lu released\n", arg);
- GOTO(out, rc = 0);
-out:
- mutex_unlock(&lli->lli_group_mutex);
-
- RETURN(rc);
+ RETURN(0);
}
/**