X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Flocks.c;h=749a0dc7cd4b674cdd974ec8ee02e271923d5401;hb=9d6a8c5c213e34c475e72b245a8eb709258e968c;hp=e0b6a80649a01ff79c26206c039ece3d4faebd0c;hpb=5a3e3b2230980cf2ce6e5e56b816dde19b993939;p=linux-2.6 diff --git a/fs/locks.c b/fs/locks.c index e0b6a80649..749a0dc7cd 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -142,12 +142,12 @@ int lease_break_time = 45; static LIST_HEAD(file_lock_list); static LIST_HEAD(blocked_list); -static kmem_cache_t *filelock_cache __read_mostly; +static struct kmem_cache *filelock_cache __read_mostly; /* Allocate an empty lock structure. */ static struct file_lock *locks_alloc_lock(void) { - return kmem_cache_alloc(filelock_cache, SLAB_KERNEL); + return kmem_cache_alloc(filelock_cache, GFP_KERNEL); } static void locks_release_private(struct file_lock *fl) @@ -199,7 +199,7 @@ EXPORT_SYMBOL(locks_init_lock); * Initialises the fields of the file lock which are invariant for * free file_locks. */ -static void init_once(void *foo, kmem_cache_t *cache, unsigned long flags) +static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags) { struct file_lock *lock = (struct file_lock *) foo; @@ -321,7 +321,7 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, start = filp->f_pos; break; case SEEK_END: - start = i_size_read(filp->f_dentry->d_inode); + start = i_size_read(filp->f_path.dentry->d_inode); break; default: return -EINVAL; @@ -371,7 +371,7 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, start = filp->f_pos; break; case SEEK_END: - start = i_size_read(filp->f_dentry->d_inode); + start = i_size_read(filp->f_path.dentry->d_inode); break; default: return -EINVAL; @@ -666,20 +666,20 @@ static int locks_block_on_timeout(struct file_lock *blocker, struct file_lock *w } int -posix_test_lock(struct file *filp, struct file_lock *fl, - struct file_lock *conflock) +posix_test_lock(struct file *filp, struct file_lock *fl) { struct file_lock *cfl; + fl->fl_type = F_UNLCK; lock_kernel(); - for (cfl = filp->f_dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) { + for (cfl = filp->f_path.dentry->d_inode->i_flock; cfl; cfl = cfl->fl_next) { if (!IS_POSIX(cfl)) continue; if (posix_locks_conflict(cfl, fl)) break; } if (cfl) { - __locks_copy_lock(conflock, cfl); + __locks_copy_lock(fl, cfl); unlock_kernel(); return 1; } @@ -734,7 +734,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) { struct file_lock *new_fl = NULL; struct file_lock **before; - struct inode * inode = filp->f_dentry->d_inode; + struct inode * inode = filp->f_path.dentry->d_inode; int error = 0; int found = 0; @@ -1018,7 +1018,7 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request */ int posix_lock_file(struct file *filp, struct file_lock *fl) { - return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, NULL); + return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, NULL); } EXPORT_SYMBOL(posix_lock_file); @@ -1033,7 +1033,7 @@ EXPORT_SYMBOL(posix_lock_file); int posix_lock_file_conf(struct file *filp, struct file_lock *fl, struct file_lock *conflock) { - return __posix_lock_file_conf(filp->f_dentry->d_inode, fl, conflock); + return __posix_lock_file_conf(filp->f_path.dentry->d_inode, fl, conflock); } EXPORT_SYMBOL(posix_lock_file_conf); @@ -1333,8 +1333,8 @@ int fcntl_getlease(struct file *filp) int type = F_UNLCK; lock_kernel(); - time_out_leases(filp->f_dentry->d_inode); - for (fl = filp->f_dentry->d_inode->i_flock; fl && IS_LEASE(fl); + time_out_leases(filp->f_path.dentry->d_inode); + for (fl = filp->f_path.dentry->d_inode->i_flock; fl && IS_LEASE(fl); fl = fl->fl_next) { if (fl->fl_file == filp) { type = fl->fl_type & ~F_INPROGRESS; @@ -1359,7 +1359,7 @@ int fcntl_getlease(struct file *filp) static int __setlease(struct file *filp, long arg, struct file_lock **flp) { struct file_lock *fl, **before, **my_before = NULL, *lease; - struct dentry *dentry = filp->f_dentry; + struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; int error, rdlease_count = 0, wrlease_count = 0; @@ -1448,7 +1448,7 @@ out: int setlease(struct file *filp, long arg, struct file_lock **lease) { - struct dentry *dentry = filp->f_dentry; + struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; int error; @@ -1482,7 +1482,7 @@ EXPORT_SYMBOL(setlease); int fcntl_setlease(unsigned int fd, struct file *filp, long arg) { struct file_lock fl, *flp = &fl; - struct dentry *dentry = filp->f_dentry; + struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; int error; @@ -1611,12 +1611,44 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) return error; } +static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) +{ + flock->l_pid = fl->fl_pid; +#if BITS_PER_LONG == 32 + /* + * Make sure we can represent the posix lock via + * legacy 32bit flock. + */ + if (fl->fl_start > OFFT_OFFSET_MAX) + return -EOVERFLOW; + if (fl->fl_end != OFFSET_MAX && fl->fl_end > OFFT_OFFSET_MAX) + return -EOVERFLOW; +#endif + flock->l_start = fl->fl_start; + flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : + fl->fl_end - fl->fl_start + 1; + flock->l_whence = 0; + return 0; +} + +#if BITS_PER_LONG == 32 +static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) +{ + flock->l_pid = fl->fl_pid; + flock->l_start = fl->fl_start; + flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : + fl->fl_end - fl->fl_start + 1; + flock->l_whence = 0; + flock->l_type = fl->fl_type; +} +#endif + /* Report the first existing lock that would conflict with l. * This implements the F_GETLK command of fcntl(). */ int fcntl_getlk(struct file *filp, struct flock __user *l) { - struct file_lock *fl, cfl, file_lock; + struct file_lock file_lock; struct flock flock; int error; @@ -1633,36 +1665,16 @@ int fcntl_getlk(struct file *filp, struct flock __user *l) if (filp->f_op && filp->f_op->lock) { error = filp->f_op->lock(filp, F_GETLK, &file_lock); - if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private) - file_lock.fl_ops->fl_release_private(&file_lock); if (error < 0) goto out; - else - fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock); - } else { - fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL); - } + } else + posix_test_lock(filp, &file_lock); - flock.l_type = F_UNLCK; - if (fl != NULL) { - flock.l_pid = fl->fl_pid; -#if BITS_PER_LONG == 32 - /* - * Make sure we can represent the posix lock via - * legacy 32bit flock. - */ - error = -EOVERFLOW; - if (fl->fl_start > OFFT_OFFSET_MAX) - goto out; - if ((fl->fl_end != OFFSET_MAX) - && (fl->fl_end > OFFT_OFFSET_MAX)) + flock.l_type = file_lock.fl_type; + if (file_lock.fl_type != F_UNLCK) { + error = posix_lock_to_flock(&flock, &file_lock); + if (error) goto out; -#endif - flock.l_start = fl->fl_start; - flock.l_len = fl->fl_end == OFFSET_MAX ? 0 : - fl->fl_end - fl->fl_start + 1; - flock.l_whence = 0; - flock.l_type = fl->fl_type; } error = -EFAULT; if (!copy_to_user(l, &flock, sizeof(flock))) @@ -1692,7 +1704,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, if (copy_from_user(&flock, l, sizeof(flock))) goto out; - inode = filp->f_dentry->d_inode; + inode = filp->f_path.dentry->d_inode; /* Don't allow mandatory locks on files that may be memory mapped * and shared. @@ -1738,7 +1750,7 @@ again: else { for (;;) { error = posix_lock_file(filp, file_lock); - if ((error != -EAGAIN) || (cmd == F_SETLK)) + if (error != -EAGAIN || cmd == F_SETLK) break; error = wait_event_interruptible(file_lock->fl_wait, !file_lock->fl_next); @@ -1770,7 +1782,7 @@ out: */ int fcntl_getlk64(struct file *filp, struct flock64 __user *l) { - struct file_lock *fl, cfl, file_lock; + struct file_lock file_lock; struct flock64 flock; int error; @@ -1787,25 +1799,15 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l) if (filp->f_op && filp->f_op->lock) { error = filp->f_op->lock(filp, F_GETLK, &file_lock); - if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private) - file_lock.fl_ops->fl_release_private(&file_lock); if (error < 0) goto out; - else - fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock); - } else { - fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL); - } + } else + posix_test_lock(filp, &file_lock); - flock.l_type = F_UNLCK; - if (fl != NULL) { - flock.l_pid = fl->fl_pid; - flock.l_start = fl->fl_start; - flock.l_len = fl->fl_end == OFFSET_MAX ? 0 : - fl->fl_end - fl->fl_start + 1; - flock.l_whence = 0; - flock.l_type = fl->fl_type; - } + flock.l_type = file_lock.fl_type; + if (file_lock.fl_type != F_UNLCK) + posix_lock_to_flock64(&flock, &file_lock); + error = -EFAULT; if (!copy_to_user(l, &flock, sizeof(flock))) error = 0; @@ -1835,7 +1837,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, if (copy_from_user(&flock, l, sizeof(flock))) goto out; - inode = filp->f_dentry->d_inode; + inode = filp->f_path.dentry->d_inode; /* Don't allow mandatory locks on files that may be memory mapped * and shared. @@ -1881,7 +1883,7 @@ again: else { for (;;) { error = posix_lock_file(filp, file_lock); - if ((error != -EAGAIN) || (cmd == F_SETLK64)) + if (error != -EAGAIN || cmd == F_SETLK64) break; error = wait_event_interruptible(file_lock->fl_wait, !file_lock->fl_next); @@ -1922,7 +1924,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner) * posix_lock_file(). Another process could be setting a lock on this * file at the same time, but we wouldn't remove that lock anyway. */ - if (!filp->f_dentry->d_inode->i_flock) + if (!filp->f_path.dentry->d_inode->i_flock) return; lock.fl_type = F_UNLCK; @@ -1951,7 +1953,7 @@ EXPORT_SYMBOL(locks_remove_posix); */ void locks_remove_flock(struct file *filp) { - struct inode * inode = filp->f_dentry->d_inode; + struct inode * inode = filp->f_path.dentry->d_inode; struct file_lock *fl; struct file_lock **before; @@ -2020,7 +2022,7 @@ static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx) struct inode *inode = NULL; if (fl->fl_file != NULL) - inode = fl->fl_file->f_dentry->d_inode; + inode = fl->fl_file->f_path.dentry->d_inode; out += sprintf(out, "%d:%s ", id, pfx); if (IS_POSIX(fl)) {