linux-and-locks-cleanup-20070202

fix linux flock, remove a bogus lock assert, and fix pid tracking to avoid useless panic
This commit is contained in:
Chaskiel M Grundman 2007-02-03 03:23:16 +00:00 committed by Derrick Brashear
parent ab294cfdc5
commit fd1c37ebe7
5 changed files with 81 additions and 10 deletions

View File

@ -606,6 +606,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
LINUX_IOP_I_PERMISSION_TAKES_NAMEIDATA
LINUX_DOP_D_REVALIDATE_TAKES_NAMEIDATA
LINUX_AOP_WRITEBACK_CONTROL
LINUX_FS_STRUCT_FOP_HAS_FLOCK
LINUX_KERNEL_LINUX_SYSCALL_H
LINUX_KERNEL_LINUX_SEQ_FILE_H
LINUX_KERNEL_SELINUX
@ -830,6 +831,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
if test "x$ac_cv_linux_init_work_has_data" = "xyes" ; then
AC_DEFINE(INIT_WORK_HAS_DATA, 1, [define if INIT_WORK takes a data (3rd) argument])
fi
if test "x$ac_cv_linux_fs_struct_fop_has_flock" = "xyes" ; then
AC_DEFINE(STRUCT_FILE_OPERATIONS_HAS_FLOCK, 1, [define if your struct file_operations has flock])
fi
:
fi
esac

View File

@ -490,7 +490,8 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp)
AFS_GUNLOCK();
#ifdef AFS_LINUX24_ENV
if (code == 0 && (cmd == F_SETLK || cmd == F_SETLKW)) {
if ((code == 0 || flp->fl_type == F_UNLCK) &&
(cmd == F_SETLK || cmd == F_SETLKW)) {
#ifdef AFS_LINUX26_ENV
struct file_lock flp2;
flp2 = *flp;
@ -499,8 +500,7 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp)
#else
code = posix_lock_file(fp, flp, 0);
#endif
osi_Assert(code != -EAGAIN); /* there should be no conflicts */
if (code) {
if (code && flp->fl_type != F_UNLCK) {
struct AFS_FLOCK flock2;
flock2 = flock;
flock2.l_type = F_UNLCK;
@ -521,6 +521,59 @@ afs_linux_lock(struct file *fp, int cmd, struct file_lock *flp)
}
#ifdef STRUCT_FILE_OPERATIONS_HAS_FLOCK
static int
afs_linux_flock(struct file *fp, int cmd, struct file_lock *flp) {
int code = 0;
struct vcache *vcp = VTOAFS(FILE_INODE(fp));
cred_t *credp = crref();
struct AFS_FLOCK flock;
/* Convert to a lock format afs_lockctl understands. */
memset((char *)&flock, 0, sizeof(flock));
flock.l_type = flp->fl_type;
flock.l_pid = flp->fl_pid;
flock.l_whence = 0;
flock.l_start = 0;
flock.l_len = OFFSET_MAX;
/* Safe because there are no large files, yet */
#if defined(F_GETLK64) && (F_GETLK != F_GETLK64)
if (cmd == F_GETLK64)
cmd = F_GETLK;
else if (cmd == F_SETLK64)
cmd = F_SETLK;
else if (cmd == F_SETLKW64)
cmd = F_SETLKW;
#endif /* F_GETLK64 && F_GETLK != F_GETLK64 */
AFS_GLOCK();
code = afs_lockctl(vcp, &flock, cmd, credp);
AFS_GUNLOCK();
if ((code == 0 || flp->fl_type == F_UNLCK) &&
(cmd == F_SETLK || cmd == F_SETLKW)) {
struct file_lock flp2;
flp2 = *flp;
flp2.fl_flags &=~ FL_SLEEP;
code = flock_lock_file_wait(fp, &flp2);
if (code && flp->fl_type != F_UNLCK) {
struct AFS_FLOCK flock2;
flock2 = flock;
flock2.l_type = F_UNLCK;
AFS_GLOCK();
afs_lockctl(vcp, &flock2, F_SETLK, credp);
AFS_GUNLOCK();
}
}
/* Convert flock back to Linux's file_lock */
flp->fl_type = flock.l_type;
flp->fl_pid = flock.l_pid;
crfree(credp);
return -code;
}
#endif
/* afs_linux_flush
* essentially the same as afs_fsync() but we need to get the return
* code for the sys_close() here, not afs_linux_release(), so call
@ -612,6 +665,9 @@ struct file_operations afs_file_fops = {
.release = afs_linux_release,
.fsync = afs_linux_fsync,
.lock = afs_linux_lock,
#ifdef STRUCT_FILE_OPERATIONS_HAS_FLOCK
.flock = afs_linux_flock,
#endif
};

View File

@ -136,8 +136,8 @@ SRXAFSCB_GetCE(struct rx_call *a_call, afs_int32 a_index,
a_result->lock.readersReading = tvc->lock.readers_reading;
a_result->lock.numWaiting = tvc->lock.num_waiting;
#if defined(INSTRUMENT_LOCKS)
a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
a_result->lock.pid_writer = tvc->lock.pid_writer;
a_result->lock.pid_last_reader = MyPidxx2Pid(tvc->lock.pid_last_reader);
a_result->lock.pid_writer = MyPidxx2Pid(tvc->lock.pid_writer);
a_result->lock.src_indicator = tvc->lock.src_indicator;
#else
/* On osf20 , the vcache does not maintain these three fields */
@ -222,8 +222,8 @@ SRXAFSCB_GetCE64(struct rx_call *a_call, afs_int32 a_index,
a_result->lock.readersReading = tvc->lock.readers_reading;
a_result->lock.numWaiting = tvc->lock.num_waiting;
#if defined(INSTRUMENT_LOCKS)
a_result->lock.pid_last_reader = tvc->lock.pid_last_reader;
a_result->lock.pid_writer = tvc->lock.pid_writer;
a_result->lock.pid_last_reader = MyPidxx2Pid(tvc->lock.pid_last_reader);
a_result->lock.pid_writer = MyPidxx2Pid(tvc->lock.pid_writer);
a_result->lock.src_indicator = tvc->lock.src_indicator;
#else
/* On osf20 , the vcache does not maintain these three fields */

View File

@ -89,7 +89,7 @@ typedef struct afs_bozoLock afs_bozoLock_t;
#if defined(AFS_SUN57_ENV)
typedef kthread_t * afs_lock_tracker_t;
#define MyPidxx (curthread)
#define MyPidxx2Pid(x) (ttoproc(x)->p_pid)
#define MyPidxx2Pid(x) (x ? ttoproc(x)->p_pid : 0)
#elif defined(AFS_SUN5_ENV) || defined(AFS_OBSD_ENV)
typedef unsigned int afs_lock_tracker_t;
#define MyPidxx (curproc->p_pid)
@ -104,7 +104,7 @@ extern tid_t thread_self();
#if defined(AFS_HPUX101_ENV)
typedef struct proc * afs_lock_tracker_t;
#define MyPidxx (u.u_procp)
#define MyPidxx2Pid(x) ((afs_int32)p_pid(x))
#define MyPidxx2Pid(x) (x ? (afs_int32)p_pid(x) : 0)
#else
#if defined(AFS_SGI64_ENV)
#if defined(AFS_SGI65_ENV)
@ -120,7 +120,7 @@ typedef unsigned int afs_lock_tracker_t;
#ifdef AFS_LINUX20_ENV
typedef struct task_struct * afs_lock_tracker_t;
#define MyPidxx (current)
#define MyPidxx2Pid(x) ((x)->pid)
#define MyPidxx2Pid(x) (x? (x)->pid : 0)
#else
#if defined(AFS_DARWIN_ENV)
#if defined(AFS_DARWIN80_ENV)

View File

@ -761,3 +761,14 @@ INIT_WORK(w,f,i);],
ac_cv_linux_init_work_has_data=no)])
AC_MSG_RESULT($ac_cv_linux_init_work_has_data)])
AC_DEFUN([LINUX_FS_STRUCT_FOP_HAS_FLOCK], [
AC_MSG_CHECKING([for flock in struct file_operations])
AC_CACHE_VAL([ac_cv_linux_fs_struct_fop_has_flock], [
AC_TRY_KBUILD(
[#include <linux/fs.h>],
[struct file_operations _fop;
_fop.flock(NULL, 0, NULL);],
ac_cv_linux_fs_struct_fop_has_flock=yes,
ac_cv_linux_fs_struct_fop_has_flock=no)])
AC_MSG_RESULT($ac_cv_linux_fs_struct_fop_has_flock)])