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
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
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)) {
struct file_lock flp2;
flp2 = *flp;
#ifdef AFS_LINUX26_ENV
flp2.fl_flags &=~ FL_SLEEP;
#endif
code = posix_lock_file(fp, &flp2);
- 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;
}
+#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
.release = afs_linux_release,
.fsync = afs_linux_fsync,
.lock = afs_linux_lock,
+#ifdef STRUCT_FILE_OPERATIONS_HAS_FLOCK
+ .flock = afs_linux_flock,
+#endif
};
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 */
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 */
#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)
#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)
#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)
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)])