|
@@ -191,27 +191,23 @@ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Encode the flock and fcntl locks for the given inode into the pagelist.
|
|
|
- * Format is: #fcntl locks, sequential fcntl locks, #flock locks,
|
|
|
- * sequential flock locks.
|
|
|
- * Must be called with lock_flocks() already held.
|
|
|
- * If we encounter more of a specific lock type than expected,
|
|
|
- * we return the value 1.
|
|
|
+ * Encode the flock and fcntl locks for the given inode into the ceph_filelock
|
|
|
+ * array. Must be called with lock_flocks() already held.
|
|
|
+ * If we encounter more of a specific lock type than expected, return -ENOSPC.
|
|
|
*/
|
|
|
-int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist,
|
|
|
- int num_fcntl_locks, int num_flock_locks)
|
|
|
+int ceph_encode_locks_to_buffer(struct inode *inode,
|
|
|
+ struct ceph_filelock *flocks,
|
|
|
+ int num_fcntl_locks, int num_flock_locks)
|
|
|
{
|
|
|
struct file_lock *lock;
|
|
|
- struct ceph_filelock cephlock;
|
|
|
int err = 0;
|
|
|
int seen_fcntl = 0;
|
|
|
int seen_flock = 0;
|
|
|
+ int l = 0;
|
|
|
|
|
|
dout("encoding %d flock and %d fcntl locks", num_flock_locks,
|
|
|
num_fcntl_locks);
|
|
|
- err = ceph_pagelist_append(pagelist, &num_fcntl_locks, sizeof(u32));
|
|
|
- if (err)
|
|
|
- goto fail;
|
|
|
+
|
|
|
for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) {
|
|
|
if (lock->fl_flags & FL_POSIX) {
|
|
|
++seen_fcntl;
|
|
@@ -219,19 +215,12 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist,
|
|
|
err = -ENOSPC;
|
|
|
goto fail;
|
|
|
}
|
|
|
- err = lock_to_ceph_filelock(lock, &cephlock);
|
|
|
+ err = lock_to_ceph_filelock(lock, &flocks[l]);
|
|
|
if (err)
|
|
|
goto fail;
|
|
|
- err = ceph_pagelist_append(pagelist, &cephlock,
|
|
|
- sizeof(struct ceph_filelock));
|
|
|
+ ++l;
|
|
|
}
|
|
|
- if (err)
|
|
|
- goto fail;
|
|
|
}
|
|
|
-
|
|
|
- err = ceph_pagelist_append(pagelist, &num_flock_locks, sizeof(u32));
|
|
|
- if (err)
|
|
|
- goto fail;
|
|
|
for (lock = inode->i_flock; lock != NULL; lock = lock->fl_next) {
|
|
|
if (lock->fl_flags & FL_FLOCK) {
|
|
|
++seen_flock;
|
|
@@ -239,19 +228,51 @@ int ceph_encode_locks(struct inode *inode, struct ceph_pagelist *pagelist,
|
|
|
err = -ENOSPC;
|
|
|
goto fail;
|
|
|
}
|
|
|
- err = lock_to_ceph_filelock(lock, &cephlock);
|
|
|
+ err = lock_to_ceph_filelock(lock, &flocks[l]);
|
|
|
if (err)
|
|
|
goto fail;
|
|
|
- err = ceph_pagelist_append(pagelist, &cephlock,
|
|
|
- sizeof(struct ceph_filelock));
|
|
|
+ ++l;
|
|
|
}
|
|
|
- if (err)
|
|
|
- goto fail;
|
|
|
}
|
|
|
fail:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Copy the encoded flock and fcntl locks into the pagelist.
|
|
|
+ * Format is: #fcntl locks, sequential fcntl locks, #flock locks,
|
|
|
+ * sequential flock locks.
|
|
|
+ * Returns zero on success.
|
|
|
+ */
|
|
|
+int ceph_locks_to_pagelist(struct ceph_filelock *flocks,
|
|
|
+ struct ceph_pagelist *pagelist,
|
|
|
+ int num_fcntl_locks, int num_flock_locks)
|
|
|
+{
|
|
|
+ int err = 0;
|
|
|
+ __le32 nlocks;
|
|
|
+
|
|
|
+ nlocks = cpu_to_le32(num_fcntl_locks);
|
|
|
+ err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks));
|
|
|
+ if (err)
|
|
|
+ goto out_fail;
|
|
|
+
|
|
|
+ err = ceph_pagelist_append(pagelist, flocks,
|
|
|
+ num_fcntl_locks * sizeof(*flocks));
|
|
|
+ if (err)
|
|
|
+ goto out_fail;
|
|
|
+
|
|
|
+ nlocks = cpu_to_le32(num_flock_locks);
|
|
|
+ err = ceph_pagelist_append(pagelist, &nlocks, sizeof(nlocks));
|
|
|
+ if (err)
|
|
|
+ goto out_fail;
|
|
|
+
|
|
|
+ err = ceph_pagelist_append(pagelist,
|
|
|
+ &flocks[num_fcntl_locks],
|
|
|
+ num_flock_locks * sizeof(*flocks));
|
|
|
+out_fail:
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Given a pointer to a lock, convert it to a ceph filelock
|
|
|
*/
|