Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acc15575 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Al Viro
Browse files

locks: new locks_mandatory_area calling convention



Pass a loff_t end for the last byte instead of the 32-bit count
parameter to allow full file clones even on 32-bit architectures.
While we're at it also simplify the read/write selection.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarJ. Bruce Fields <bfields@fieldses.org>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent eac70053
Loading
Loading
Loading
Loading
+9 −13
Original line number Diff line number Diff line
@@ -1227,20 +1227,16 @@ int locks_mandatory_locked(struct file *file)

/**
 * locks_mandatory_area - Check for a conflicting lock
 * @read_write: %FLOCK_VERIFY_WRITE for exclusive access, %FLOCK_VERIFY_READ
 *		for shared
 * @inode:	the file to check
 * @filp:       how the file was opened (if it was)
 * @offset:     start of area to check
 * @count:      length of area to check
 * @start:	first byte in the file to check
 * @end:	lastbyte in the file to check
 * @type:	%F_WRLCK for a write lock, else %F_RDLCK
 *
 * Searches the inode's list of locks to find any POSIX locks which conflict.
 * This function is called from rw_verify_area() and
 * locks_verify_truncate().
 */
int locks_mandatory_area(int read_write, struct inode *inode,
			 struct file *filp, loff_t offset,
			 size_t count)
int locks_mandatory_area(struct inode *inode, struct file *filp, loff_t start,
			 loff_t end, unsigned char type)
{
	struct file_lock fl;
	int error;
@@ -1252,9 +1248,9 @@ int locks_mandatory_area(int read_write, struct inode *inode,
	fl.fl_flags = FL_POSIX | FL_ACCESS;
	if (filp && !(filp->f_flags & O_NONBLOCK))
		sleep = true;
	fl.fl_type = (read_write == FLOCK_VERIFY_WRITE) ? F_WRLCK : F_RDLCK;
	fl.fl_start = offset;
	fl.fl_end = offset + count - 1;
	fl.fl_type = type;
	fl.fl_start = start;
	fl.fl_end = end;

	for (;;) {
		if (filp) {
+2 −3
Original line number Diff line number Diff line
@@ -396,9 +396,8 @@ int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t
	}

	if (unlikely(inode->i_flctx && mandatory_lock(inode))) {
		retval = locks_mandatory_area(
			read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
			inode, file, pos, count);
		retval = locks_mandatory_area(inode, file, pos, pos + count - 1,
				read_write == READ ? F_RDLCK : F_WRLCK);
		if (retval < 0)
			return retval;
	}
+14 −16
Original line number Diff line number Diff line
@@ -2030,12 +2030,9 @@ extern struct kobject *fs_kobj;

#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)

#define FLOCK_VERIFY_READ  1
#define FLOCK_VERIFY_WRITE 2

#ifdef CONFIG_FILE_LOCKING
extern int locks_mandatory_locked(struct file *);
extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
extern int locks_mandatory_area(struct inode *, struct file *, loff_t, loff_t, unsigned char);

/*
 * Candidates for mandatory locking have the setgid bit set
@@ -2065,17 +2062,19 @@ static inline int locks_verify_locked(struct file *file)
}

static inline int locks_verify_truncate(struct inode *inode,
				    struct file *filp,
				    struct file *f,
				    loff_t size)
{
	if (inode->i_flctx && mandatory_lock(inode))
		return locks_mandatory_area(
			FLOCK_VERIFY_WRITE, inode, filp,
			size < inode->i_size ? size : inode->i_size,
			(size < inode->i_size ? inode->i_size - size
			 : size - inode->i_size)
		);
	if (!inode->i_flctx || !mandatory_lock(inode))
		return 0;

	if (size < inode->i_size) {
		return locks_mandatory_area(inode, f, size, inode->i_size - 1,
				F_WRLCK);
	} else {
		return locks_mandatory_area(inode, f, inode->i_size, size - 1,
				F_WRLCK);
	}
}

static inline int break_lease(struct inode *inode, unsigned int mode)
@@ -2144,9 +2143,8 @@ static inline int locks_mandatory_locked(struct file *file)
	return 0;
}

static inline int locks_mandatory_area(int rw, struct inode *inode,
				       struct file *filp, loff_t offset,
				       size_t count)
static inline int locks_mandatory_area(struct inode *inode, struct file *filp,
		loff_t start, loff_t end, unsigned char type)
{
	return 0;
}