staticinline u64 secure_addr(void *addr)
{
u64 v = lock_secret ^ (u64)(unsignedlong)addr; /* * Set the most significant bit, so that MDS knows the 'owner' * is sufficient to identify the owner of lock. (old code uses * both 'owner' and 'pid')
*/
v |= (1ULL << 63); return v;
}
/* * Do not use the 'fl->fl_file' in release function, which * is possibly already released by another thread.
*/ staticvoid ceph_fl_release_lock(struct file_lock *fl)
{ struct inode *inode = fl->fl_u.ceph.inode; struct ceph_inode_info *ci;
/* * If inode is NULL it should be a request file_lock, * nothing we can do.
*/ if (!inode) return;
ci = ceph_inode(inode); if (atomic_dec_and_test(&ci->i_filelock_ref)) { /* clear error when all locks are released */
spin_lock(&ci->i_ceph_lock);
ci->i_ceph_flags &= ~CEPH_I_ERROR_FILELOCK;
spin_unlock(&ci->i_ceph_lock);
}
fl->fl_u.ceph.inode = NULL;
iput(inode);
}
if (operation == CEPH_MDS_OP_SETFILELOCK) { /* * increasing i_filelock_ref closes race window between * handling request reply and adding file_lock struct to * inode. Otherwise, auth caps may get trimmed in the * window. Caller function will decrease the counter.
*/
fl->fl_ops = &ceph_fl_lock_ops;
fl->fl_ops->fl_copy_lock(fl, NULL);
}
/* * Attempt to set an fcntl lock. * For now, this just goes away to the server. Later it may be more awesome.
*/ int ceph_lock(struct file *file, int cmd, struct file_lock *fl)
{ struct inode *inode = file_inode(file); struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_client *cl = ceph_inode_to_client(inode); int err = 0;
u16 op = CEPH_MDS_OP_SETFILELOCK;
u8 wait = 0;
u8 lock_cmd;
if (!(fl->c.flc_flags & FL_POSIX)) return -ENOLCK;
if (ceph_inode_is_shutdown(inode)) return -ESTALE;
doutc(cl, "fl_owner: %p\n", fl->c.flc_owner);
/* set wait bit as appropriate, then make command as Ceph expects it*/ if (IS_GETLK(cmd))
op = CEPH_MDS_OP_GETFILELOCK; elseif (IS_SETLKW(cmd))
wait = 1;
spin_lock(&ci->i_ceph_lock); if (ci->i_ceph_flags & CEPH_I_ERROR_FILELOCK) {
err = -EIO;
}
spin_unlock(&ci->i_ceph_lock); if (err < 0) { if (op == CEPH_MDS_OP_SETFILELOCK && lock_is_unlock(fl))
posix_lock_file(file, fl, NULL); return err;
}
/* * Fills in the passed counter variables, so you can prepare pagelist metadata * before calling ceph_encode_locks.
*/ void ceph_count_locks(struct inode *inode, int *fcntl_count, int *flock_count)
{ struct ceph_client *cl = ceph_inode_to_client(inode); struct file_lock *lock; struct file_lock_context *ctx;
/* * Given a pointer to a lock, convert it to a ceph filelock
*/ staticint lock_to_ceph_filelock(struct inode *inode, struct file_lock *lock, struct ceph_filelock *cephlock)
{ struct ceph_client *cl = ceph_inode_to_client(inode); int err = 0;
switch (lock->c.flc_type) { case F_RDLCK:
cephlock->type = CEPH_LOCK_SHARED; break; case F_WRLCK:
cephlock->type = CEPH_LOCK_EXCL; break; case F_UNLCK:
cephlock->type = CEPH_LOCK_UNLOCK; break; default:
doutc(cl, "Have unknown lock type %d\n",
lock->c.flc_type);
err = -EINVAL;
}
return err;
}
/* * Encode the flock and fcntl locks for the given inode into the ceph_filelock * array. Must be called with inode->i_lock already held. * If we encounter more of a specific lock type than expected, return -ENOSPC.
*/ 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 file_lock_context *ctx = locks_inode_context(inode); struct ceph_client *cl = ceph_inode_to_client(inode); int err = 0; int seen_fcntl = 0; int seen_flock = 0; int l = 0;
doutc(cl, "encoding %d flock and %d fcntl locks\n", num_flock_locks,
num_fcntl_locks);
/* * 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;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.