#define ATTR_BLOCKS 0x4000
#define ATTR_KILL_SUID 0
#define ATTR_KILL_SGID 0
+#define ATTR_FILE 0
struct iattr {
unsigned int ia_valid;
io->u.ci_setattr.sa_valid = attr->ia_valid;
io->u.ci_setattr.sa_capa = capa;
- if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0)
+ if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) {
+ struct ccc_io *cio = ccc_env_io(env);
+
+ if (attr->ia_valid & ATTR_FILE)
+ /* populate the file descriptor for ftruncate to honor
+ * group lock - see LU-787 */
+ cio->cui_fd = cl_iattr2fd(inode, attr);
+
result = cl_io_loop(env, io);
- else
+ } else {
result = io->ci_result;
+ }
cl_io_fini(env, io);
cl_env_put(env, &refcheck);
RETURN(result);
#define cl_isize_write(inode,kms) do{llu_i2stat(inode)->st_size = kms;}while(0)
#define cl_isize_write_nolock(inode,kms) cl_isize_write(inode,kms)
+static inline struct ll_file_data *cl_iattr2fd(struct inode *inode,
+ const struct iattr *attr)
+{
+ return llu_i2info(inode)->lli_file_data;
+}
+
static inline void cl_isize_lock(struct inode *inode, int lsmlock)
{
}
#define cl_inode_mode(inode) ((inode)->i_mode)
#define cl_i2sbi ll_i2sbi
+static inline struct ll_file_data *cl_iattr2fd(struct inode *inode,
+ const struct iattr *attr)
+{
+ LASSERT(attr->ia_valid & ATTR_FILE);
+ return LUSTRE_FPRIVATE(attr->ia_file);
+}
+
static inline void cl_isize_lock(struct inode *inode, int lsmlock)
{
ll_inode_size_lock(inode, lsmlock);
" d mkdir\n"
" D open(O_DIRECTORY)\n"
" f statfs\n"
+" G gid get grouplock\n"
+" g gid put grouplock\n"
" L link\n"
" l symlink\n"
" m mknod\n"
int flags;
int save_errno;
int verbose = 0;
+ int gid = 0;
if (argc < 3) {
fprintf(stderr, usage, argv[0]);
exit(save_errno);
}
break;
+ case 'G':
+ gid = atoi(commands+1);
+ if (ioctl(fd, LL_IOC_GROUP_LOCK, gid) == -1) {
+ save_errno = errno;
+ perror("ioctl(GROUP_LOCK)");
+ exit(save_errno);
+ }
+ break;
+ case 'g':
+ gid = atoi(commands+1);
+ if (ioctl(fd, LL_IOC_GROUP_UNLOCK, gid) == -1) {
+ save_errno = errno;
+ perror("ioctl(GROUP_UNLOCK)");
+ exit(save_errno);
+ }
+ break;
case 'l':
newfile = POP_ARG();
if (!newfile)
}
run_test 34g "truncate long file ==============================="
+test_34h() {
+ local gid=10
+ local sz=1000
+
+ dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error
+ multiop $DIR/$tfile OG${gid}T${sz}g${gid}c &
+ MULTIPID=$!
+ sleep 2
+
+ if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
+ error "Multiop blocked on ftruncate, pid=$MULTIPID"
+ kill -9 $MULTIPID
+ fi
+ wait $MULTIPID
+ local nsz=`stat -c %s $DIR/$tfile`
+ [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
+}
+run_test 34h "ftruncate file under grouplock should not block"
+
test_35a() {
cp /bin/sh $DIR/f35a
chmod 444 $DIR/f35a