X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Flocks.c;h=9f4fd59c1aaa4cc19e5ce60522d34d021b9efd56;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=8724f22133d99b3567165d73f503ba25bda9f235;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/fs/locks.c b/fs/locks.c index 8724f2213..9f4fd59c1 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -125,6 +125,7 @@ #include #include #include +#include #include #include @@ -140,53 +141,43 @@ int lease_break_time = 45; #define for_each_lock(inode, lockp) \ for (lockp = &inode->i_flock; *lockp != NULL; lockp = &(*lockp)->fl_next) -LIST_HEAD(file_lock_list); - -EXPORT_SYMBOL(file_lock_list); - +static LIST_HEAD(file_lock_list); static LIST_HEAD(blocked_list); -static kmem_cache_t *filelock_cache; +static struct kmem_cache *filelock_cache __read_mostly; /* Allocate an empty lock structure. */ static struct file_lock *locks_alloc_lock(void) { if (!vx_locks_avail(1)) return NULL; - return kmem_cache_alloc(filelock_cache, SLAB_KERNEL); + return kmem_cache_alloc(filelock_cache, GFP_KERNEL); } -/* Free a lock which is not in use. */ -static void locks_free_lock(struct file_lock *fl) +static void locks_release_private(struct file_lock *fl) { - if (fl == NULL) { - BUG(); - return; - } - - vx_locks_dec(fl); - - if (waitqueue_active(&fl->fl_wait)) - panic("Attempting to free lock with active wait queue"); - - if (!list_empty(&fl->fl_block)) - panic("Attempting to free lock with active block list"); - - if (!list_empty(&fl->fl_link)) - panic("Attempting to free lock on active lock list"); - if (fl->fl_ops) { if (fl->fl_ops->fl_release_private) fl->fl_ops->fl_release_private(fl); fl->fl_ops = NULL; } - if (fl->fl_lmops) { if (fl->fl_lmops->fl_release_private) fl->fl_lmops->fl_release_private(fl); fl->fl_lmops = NULL; } +} + +/* Free a lock which is not in use. */ +static void locks_free_lock(struct file_lock *fl) +{ + BUG_ON(waitqueue_active(&fl->fl_wait)); + BUG_ON(!list_empty(&fl->fl_block)); + BUG_ON(!list_empty(&fl->fl_link)); + + vx_locks_dec(fl); + locks_release_private(fl); kmem_cache_free(filelock_cache, fl); } @@ -214,7 +205,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; @@ -225,26 +216,47 @@ static void init_once(void *foo, kmem_cache_t *cache, unsigned long flags) locks_init_lock(lock); } +static void locks_copy_private(struct file_lock *new, struct file_lock *fl) +{ + if (fl->fl_ops) { + if (fl->fl_ops->fl_copy_lock) + fl->fl_ops->fl_copy_lock(new, fl); + new->fl_ops = fl->fl_ops; + } + if (fl->fl_lmops) { + if (fl->fl_lmops->fl_copy_lock) + fl->fl_lmops->fl_copy_lock(new, fl); + new->fl_lmops = fl->fl_lmops; + } +} + /* * Initialize a new lock from an existing file_lock structure. */ -void locks_copy_lock(struct file_lock *new, struct file_lock *fl) +static void __locks_copy_lock(struct file_lock *new, const struct file_lock *fl) { new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; - new->fl_file = fl->fl_file; + new->fl_file = NULL; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; new->fl_start = fl->fl_start; new->fl_end = fl->fl_end; + new->fl_ops = NULL; + new->fl_lmops = NULL; +} + +void locks_copy_lock(struct file_lock *new, struct file_lock *fl) +{ + locks_release_private(new); + + __locks_copy_lock(new, fl); + new->fl_file = fl->fl_file; new->fl_ops = fl->fl_ops; new->fl_lmops = fl->fl_lmops; - if (fl->fl_ops && fl->fl_ops->fl_copy_lock) - fl->fl_ops->fl_copy_lock(new, fl); - if (fl->fl_lmops && fl->fl_lmops->fl_copy_lock) - fl->fl_lmops->fl_copy_lock(new, fl); - new->fl_xid = fl->fl_xid; + + locks_copy_private(new, fl); } EXPORT_SYMBOL(locks_copy_lock); @@ -282,6 +294,8 @@ static int flock_make_lock(struct file *filp, struct file_lock **lock, fl->fl_type = type; fl->fl_end = OFFSET_MAX; + vxd_assert(filp->f_xid == vx_current_xid(), + "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid()); fl->fl_xid = filp->f_xid; vx_locks_inc(fl); @@ -312,14 +326,14 @@ static int flock_to_posix_lock(struct file *filp, struct file_lock *fl, off_t start, end; switch (l->l_whence) { - case 0: /*SEEK_SET*/ + case SEEK_SET: start = 0; break; - case 1: /*SEEK_CUR*/ + case SEEK_CUR: start = filp->f_pos; break; - case 2: /*SEEK_END*/ - start = i_size_read(filp->f_dentry->d_inode); + case SEEK_END: + start = i_size_read(filp->f_path.dentry->d_inode); break; default: return -EINVAL; @@ -362,14 +376,14 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl, loff_t start; switch (l->l_whence) { - case 0: /*SEEK_SET*/ + case SEEK_SET: start = 0; break; - case 1: /*SEEK_CUR*/ + case SEEK_CUR: start = filp->f_pos; break; - case 2: /*SEEK_END*/ - start = i_size_read(filp->f_dentry->d_inode); + case SEEK_END: + start = i_size_read(filp->f_path.dentry->d_inode); break; default: return -EINVAL; @@ -470,6 +484,9 @@ static int lease_alloc(struct file *filp, int type, struct file_lock **flp) goto out; fl->fl_xid = vx_current_xid(); + if (filp) + vxd_assert(filp->f_xid == fl->fl_xid, + "f_xid(%d) == fl_xid(%d)", filp->f_xid, fl->fl_xid); vx_locks_inc(fl); error = lease_init(filp, type, fl); if (error) { @@ -527,12 +544,7 @@ static void locks_delete_block(struct file_lock *waiter) static void locks_insert_block(struct file_lock *blocker, struct file_lock *waiter) { - if (!list_empty(&waiter->fl_block)) { - printk(KERN_ERR "locks_insert_block: removing duplicated lock " - "(pid=%d %Ld-%Ld type=%d)\n", waiter->fl_pid, - waiter->fl_start, waiter->fl_end, waiter->fl_type); - __locks_delete_block(waiter); - } + BUG_ON(!list_empty(&waiter->fl_block)); list_add_tail(&waiter->fl_block, &blocker->fl_block); waiter->fl_next = blocker; if (IS_POSIX(blocker)) @@ -671,21 +683,26 @@ static int locks_block_on_timeout(struct file_lock *blocker, struct file_lock *w return result; } -struct file_lock * -posix_test_lock(struct file *filp, struct file_lock *fl) +int +posix_test_lock(struct file *filp, struct file_lock *fl, + struct file_lock *conflock) { struct file_lock *cfl; 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); + unlock_kernel(); + return 1; + } unlock_kernel(); - - return (cfl); + return 0; } EXPORT_SYMBOL(posix_test_lock); @@ -704,7 +721,7 @@ EXPORT_SYMBOL(posix_test_lock); * from a broken NFS client. But broken NFS clients have a lot more to * worry about than proper deadlock detection anyway... --okir */ -int posix_locks_deadlock(struct file_lock *caller_fl, +static int posix_locks_deadlock(struct file_lock *caller_fl, struct file_lock *block_fl) { struct list_head *tmp; @@ -723,21 +740,25 @@ next_task: return 0; } -EXPORT_SYMBOL(posix_locks_deadlock); - /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks * at the head of the list, but that's secret knowledge known only to * flock_lock_file and posix_lock_file. + * + * Note that if called with an FL_EXISTS argument, the caller may determine + * whether or not a lock was successfully freed by testing the return + * value for -ENOENT. */ 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; lock_kernel(); + if (request->fl_flags & FL_ACCESS) + goto find_conflict; for_each_lock(inode, before) { struct file_lock *fl = *before; if (IS_POSIX(fl)) @@ -753,9 +774,13 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) break; } - if (request->fl_type == F_UNLCK) + if (request->fl_type == F_UNLCK) { + if ((request->fl_flags & FL_EXISTS) && !found) + error = -ENOENT; goto out; + } + error = -ENOMEM; new_fl = locks_alloc_lock(); if (new_fl == NULL) goto out; @@ -766,6 +791,8 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) if (found) cond_resched(); + new_fl->fl_xid = -1; +find_conflict: for_each_lock(inode, before) { struct file_lock *fl = *before; if (IS_POSIX(fl)) @@ -779,10 +806,13 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) locks_insert_block(fl, request); goto out; } + if (request->fl_flags & FL_ACCESS) + goto out; locks_copy_lock(new_fl, request); - vx_locks_inc(new_fl); locks_insert_lock(&inode->i_flock, new_fl); + vx_locks_inc(new_fl); new_fl = NULL; + error = 0; out: unlock_kernel(); @@ -791,27 +821,35 @@ out: return error; } -EXPORT_SYMBOL(posix_lock_file); - -static int __posix_lock_file(struct inode *inode, struct file_lock *request, xid_t xid) +static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request, + struct file_lock *conflock, xid_t xid) { struct file_lock *fl; - struct file_lock *new_fl, *new_fl2; + struct file_lock *new_fl = NULL; + struct file_lock *new_fl2 = NULL; struct file_lock *left = NULL; struct file_lock *right = NULL; struct file_lock **before; int error, added = 0; + vxd_assert(xid == vx_current_xid(), + "xid(%d) == current(%d)", xid, vx_current_xid()); /* * We may need two file_lock structures for this operation, * so we get them in advance to avoid races. + * + * In some cases we can be sure, that no new locks will be needed */ - new_fl = locks_alloc_lock(); - new_fl->fl_xid = xid; - vx_locks_inc(new_fl); - new_fl2 = locks_alloc_lock(); - new_fl2->fl_xid = xid; - vx_locks_inc(new_fl2); + if (!(request->fl_flags & FL_ACCESS) && + (request->fl_type != F_UNLCK || + request->fl_start != 0 || request->fl_end != OFFSET_MAX)) { + new_fl = locks_alloc_lock(); + new_fl->fl_xid = xid; + vx_locks_inc(new_fl); + new_fl2 = locks_alloc_lock(); + new_fl2->fl_xid = xid; + vx_locks_inc(new_fl2); + } lock_kernel(); if (request->fl_type != F_UNLCK) { @@ -821,6 +859,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, xid continue; if (!posix_locks_conflict(request, fl)) continue; + if (conflock) + locks_copy_lock(conflock, fl); error = -EAGAIN; if (!(request->fl_flags & FL_SLEEP)) goto out; @@ -838,14 +878,7 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, xid if (request->fl_flags & FL_ACCESS) goto out; - error = -ENOLCK; /* "no luck" */ - if (!(new_fl && new_fl2)) - goto out; - /* - * We've allocated the new locks in advance, so there are no - * errors possible (and no blocking operations) from here on. - * * Find the first old lock with the same owner as the new lock. */ @@ -930,7 +963,8 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, xid fl->fl_start = request->fl_start; fl->fl_end = request->fl_end; fl->fl_type = request->fl_type; - fl->fl_u = request->fl_u; + locks_release_private(fl); + locks_copy_private(fl, request); request = fl; added = 1; } @@ -941,10 +975,28 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, xid before = &fl->fl_next; } + /* + * The above code only modifies existing locks in case of + * merging or replacing. If new lock(s) need to be inserted + * all modifications are done bellow this, so it's safe yet to + * bail out. + */ + error = -ENOLCK; /* "no luck" */ + if (right && left == right && !new_fl2) + goto out; + error = 0; if (!added) { - if (request->fl_type == F_UNLCK) + if (request->fl_type == F_UNLCK) { + if (request->fl_flags & FL_EXISTS) + error = -ENOENT; goto out; + } + + if (!new_fl) { + error = -ENOLCK; + goto out; + } locks_copy_lock(new_fl, request); locks_insert_lock(before, new_fl); new_fl = NULL; @@ -986,11 +1038,33 @@ static int __posix_lock_file(struct inode *inode, struct file_lock *request, xid * Add a POSIX style lock to a file. * We merge adjacent & overlapping locks whenever possible. * POSIX locks are sorted by owner task, then by starting address + * + * Note that if called with an FL_EXISTS argument, the caller may determine + * whether or not a lock was successfully freed by testing the return + * value for -ENOENT. */ int posix_lock_file(struct file *filp, struct file_lock *fl) { - return __posix_lock_file(filp->f_dentry->d_inode, fl, filp->f_xid); + return __posix_lock_file_conf(filp->f_path.dentry->d_inode, + fl, NULL, filp->f_xid); +} +EXPORT_SYMBOL(posix_lock_file); + +/** + * posix_lock_file_conf - Apply a POSIX-style lock to a file + * @filp: The file to apply the lock to + * @fl: The lock to be applied + * @conflock: Place to return a copy of the conflicting lock, if found. + * + * Except for the conflock parameter, acts just like 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_path.dentry->d_inode, + fl, conflock, filp->f_xid); } +EXPORT_SYMBOL(posix_lock_file_conf); /** * posix_lock_file_wait - Apply a POSIX-style lock to a file @@ -1006,8 +1080,7 @@ int posix_lock_file_wait(struct file *filp, struct file_lock *fl) int error; might_sleep (); for (;;) { - error = __posix_lock_file(filp->f_dentry->d_inode, - fl, filp->f_xid); + error = posix_lock_file(filp, fl); if ((error != -EAGAIN) || !(fl->fl_flags & FL_SLEEP)) break; error = wait_event_interruptible(fl->fl_wait, !fl->fl_next); @@ -1079,7 +1152,7 @@ int locks_mandatory_area(int read_write, struct inode *inode, fl.fl_end = offset + count - 1; for (;;) { - error = __posix_lock_file(inode, &fl, filp->f_xid); + error = __posix_lock_file_conf(inode, &fl, NULL, filp->f_xid); if (error != -EAGAIN) break; if (!(fl.fl_flags & FL_SLEEP)) @@ -1289,8 +1362,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; @@ -1315,7 +1388,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; @@ -1383,8 +1456,8 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp) goto out; locks_copy_lock(fl, lease); - locks_insert_lock(before, fl); + vx_locks_inc(fl); *flp = fl; error = 0; @@ -1404,7 +1477,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; @@ -1438,7 +1511,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; @@ -1470,7 +1543,7 @@ int fcntl_setlease(unsigned int fd, struct file *filp, long arg) goto out_unlock; } - error = f_setown(filp, current->pid, 0); + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); out_unlock: unlock_kernel(); return error; @@ -1572,7 +1645,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) */ int fcntl_getlk(struct file *filp, struct flock __user *l) { - struct file_lock *fl, file_lock; + struct file_lock *fl, cfl, file_lock; struct flock flock; int error; @@ -1596,7 +1669,7 @@ int fcntl_getlk(struct file *filp, struct flock __user *l) else fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock); } else { - fl = posix_test_lock(filp, &file_lock); + fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL); } flock.l_type = F_UNLCK; @@ -1641,6 +1714,8 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, if (file_lock == NULL) return -ENOLCK; + vxd_assert(filp->f_xid == vx_current_xid(), + "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid()); file_lock->fl_xid = filp->f_xid; vx_locks_inc(file_lock); @@ -1651,7 +1726,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. @@ -1696,8 +1771,7 @@ again: error = filp->f_op->lock(filp, cmd, file_lock); else { for (;;) { - error = __posix_lock_file(inode, file_lock, - filp->f_xid); + error = posix_lock_file(filp, file_lock); if ((error != -EAGAIN) || (cmd == F_SETLK)) break; error = wait_event_interruptible(file_lock->fl_wait, @@ -1730,7 +1804,7 @@ out: */ int fcntl_getlk64(struct file *filp, struct flock64 __user *l) { - struct file_lock *fl, file_lock; + struct file_lock *fl, cfl, file_lock; struct flock64 flock; int error; @@ -1754,7 +1828,7 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l) else fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock); } else { - fl = posix_test_lock(filp, &file_lock); + fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL); } flock.l_type = F_UNLCK; @@ -1788,6 +1862,8 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, if (file_lock == NULL) return -ENOLCK; + vxd_assert(filp->f_xid == vx_current_xid(), + "f_xid(%d) == current(%d)", filp->f_xid, vx_current_xid()); file_lock->fl_xid = filp->f_xid; vx_locks_inc(file_lock); @@ -1798,7 +1874,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. @@ -1843,8 +1919,7 @@ again: error = filp->f_op->lock(filp, cmd, file_lock); else { for (;;) { - error = __posix_lock_file(inode, file_lock, - filp->f_xid); + error = posix_lock_file(filp, file_lock); if ((error != -EAGAIN) || (cmd == F_SETLK64)) break; error = wait_event_interruptible(file_lock->fl_wait, @@ -1879,19 +1954,18 @@ out: */ void locks_remove_posix(struct file *filp, fl_owner_t owner) { - struct file_lock lock, **before; + struct file_lock lock; /* * If there are no locks held on this file, we don't need to call * 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. */ - before = &filp->f_dentry->d_inode->i_flock; - if (*before == NULL) + if (!filp->f_path.dentry->d_inode->i_flock) return; lock.fl_type = F_UNLCK; - lock.fl_flags = FL_POSIX; + lock.fl_flags = FL_POSIX | FL_CLOSE; lock.fl_start = 0; lock.fl_end = OFFSET_MAX; lock.fl_owner = owner; @@ -1900,25 +1974,11 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner) lock.fl_ops = NULL; lock.fl_lmops = NULL; - if (filp->f_op && filp->f_op->lock != NULL) { + if (filp->f_op && filp->f_op->lock != NULL) filp->f_op->lock(filp, F_SETLK, &lock); - goto out; - } + else + posix_lock_file(filp, &lock); - /* Can't use posix_lock_file here; we need to remove it no matter - * which pid we have. - */ - lock_kernel(); - while (*before != NULL) { - struct file_lock *fl = *before; - if (IS_POSIX(fl) && posix_same_owner(fl, &lock)) { - locks_delete_lock(before); - continue; - } - before = &fl->fl_next; - } - unlock_kernel(); -out: if (lock.fl_ops && lock.fl_ops->fl_release_private) lock.fl_ops->fl_release_private(&lock); } @@ -1930,7 +1990,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; @@ -1971,21 +2031,6 @@ void locks_remove_flock(struct file *filp) unlock_kernel(); } -/** - * posix_block_lock - blocks waiting for a file lock - * @blocker: the lock which is blocking - * @waiter: the lock which conflicts and has to wait - * - * lockd needs to block waiting for locks. - */ -void -posix_block_lock(struct file_lock *blocker, struct file_lock *waiter) -{ - locks_insert_block(blocker, waiter); -} - -EXPORT_SYMBOL(posix_block_lock); - /** * posix_unblock_lock - stop waiting for a file lock * @filp: how the file was opened @@ -2014,7 +2059,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)) { @@ -2118,7 +2163,7 @@ int get_locks_status(char *buffer, char **start, off_t offset, int length) struct list_head *btmp; struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link); - if (!vx_check(fl->fl_xid, VX_IDENT|VX_WATCH)) + if (!vx_check(fl->fl_xid, VS_WATCH_P|VS_IDENT)) continue; lock_get_status(q, fl, ++i, ""); @@ -2223,63 +2268,6 @@ int lock_may_write(struct inode *inode, loff_t start, unsigned long len) EXPORT_SYMBOL(lock_may_write); -static inline void __steal_locks(struct file *file, fl_owner_t from) -{ - struct inode *inode = file->f_dentry->d_inode; - struct file_lock *fl = inode->i_flock; - - while (fl) { - if (fl->fl_file == file && fl->fl_owner == from) - fl->fl_owner = current->files; - fl = fl->fl_next; - } -} - -/* When getting ready for executing a binary, we make sure that current - * has a files_struct on its own. Before dropping the old files_struct, - * we take over ownership of all locks for all file descriptors we own. - * Note that we may accidentally steal a lock for a file that a sibling - * has created since the unshare_files() call. - */ -void steal_locks(fl_owner_t from) -{ - struct files_struct *files = current->files; - int i, j; - struct fdtable *fdt; - - if (from == files) - return; - - lock_kernel(); - j = 0; - - /* - * We are not taking a ref to the file structures, so - * we need to acquire ->file_lock. - */ - spin_lock(&files->file_lock); - fdt = files_fdtable(files); - for (;;) { - unsigned long set; - i = j * __NFDBITS; - if (i >= fdt->max_fdset || i >= fdt->max_fds) - break; - set = fdt->open_fds->fds_bits[j++]; - while (set) { - if (set & 1) { - struct file *file = fdt->fd[i]; - if (file) - __steal_locks(file, from); - } - i++; - set >>= 1; - } - } - spin_unlock(&files->file_lock); - unlock_kernel(); -} -EXPORT_SYMBOL(steal_locks); - static int __init filelock_init(void) { filelock_cache = kmem_cache_create("file_lock_cache",