diff options
author | Vikas Gorur <vikas@zresearch.com> | 2009-02-27 02:14:15 +0530 |
---|---|---|
committer | Anand V. Avati <avati@amp.gluster.com> | 2009-02-27 02:36:04 +0530 |
commit | 2dbcb3c79338dc4f4c45c21e4bf62e61e455ae19 (patch) | |
tree | 42ce3c02dc2f8adf741ee505ef21dae85a9f715a | |
parent | f097e77ffb386dc73e3639af4a9cd57df0d3d40d (diff) |
reverting nested locks in posix-locks for inodelk
Signed-off-by: Anand V. Avati <avati@amp.gluster.com>
-rw-r--r-- | doc/user-guide/user-guide.info | 117 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-transaction.c | 2 | ||||
-rw-r--r-- | xlators/features/locks/src/common.c | 90 | ||||
-rw-r--r-- | xlators/features/locks/src/common.h | 9 | ||||
-rw-r--r-- | xlators/features/locks/src/internal.c | 381 | ||||
-rw-r--r-- | xlators/features/locks/src/locks.h | 8 | ||||
-rw-r--r-- | xlators/features/locks/src/posix.c | 8 |
7 files changed, 350 insertions, 265 deletions
diff --git a/doc/user-guide/user-guide.info b/doc/user-guide/user-guide.info index 078d62adef1..e80014c459b 100644 --- a/doc/user-guide/user-guide.info +++ b/doc/user-guide/user-guide.info @@ -1,5 +1,4 @@ -This is ../../../doc/user-guide/user-guide.info, produced by makeinfo -version 4.9 from ../../../doc/user-guide/user-guide.texi. +This is ../../../doc/user-guide/user-guide.info, produced by makeinfo version 4.13 from ../../../doc/user-guide/user-guide.texi. START-INFO-DIR-ENTRY * GlusterFS: (user-guide). GlusterFS distributed filesystem user guide @@ -7,7 +6,7 @@ END-INFO-DIR-ENTRY This is the user manual for GlusterFS 2.0. - Copyright (C) 2008,2007 <Z> Research, Inc. Permission is granted to + Copyright (C) 2007-2009 <Z> Research, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no @@ -22,7 +21,7 @@ GlusterFS 2.0 User Guide This is the user manual for GlusterFS 2.0. - Copyright (C) 2008,2007 <Z> Research, Inc. Permission is granted to + Copyright (C) 2007-2009 <Z> Research, Inc. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no @@ -360,7 +359,7 @@ File: user-guide.info, Node: Server, Next: Client, Up: Running GlusterFS ------------ The GlusterFS server is necessary to export storage volumes to remote -clients (See *Note Server protocol:: for more info). This section +clients (See *note Server protocol:: for more info). This section documents the invocation of the GlusterFS server program and all the command-line options accepted by it. @@ -826,7 +825,7 @@ File: user-guide.info, Node: POSIX, Next: BDB, Up: Storage Translators filesystem that supports extended attributes (EXT3, ReiserFS, XFS, ...). Extended attributes are used by some translators to store metadata, for example, by the replicate and stripe translators. See -*Note Replicate:: and *Note Stripe::, respectively for details. +*note Replicate:: and *note Stripe::, respectively for details. `directory <path>' The directory on the local filesystem which is to be used for @@ -1043,7 +1042,7 @@ accessible to remote GlusterFS clients. `client-volume-filename <path> (<CONFDIR>/glusterfs-client.vol)' The volume specification file to use for the client. This is the file the client will receive when it is invoked with the - `--server' option (*Note Client::). + `--server' option (*note Client::). `transport-type [tcp,ib-verbs,ib-sdp] (tcp)' The transport to use. You should use the server versions of all @@ -1646,7 +1645,7 @@ File: user-guide.info, Node: Booster, Prev: IO Cache, Up: Performance Transla The booster translator gives applications a faster path to communicate read and write requests to GlusterFS. Normally, all requests to GlusterFS from applications go through FUSE, as indicated -in *Note Filesystems in Userspace::. Using the booster translator in +in *note Filesystems in Userspace::. Using the booster translator in conjunction with the GlusterFS booster shared library, an application can bypass the FUSE path and send read/write requests directly to the GlusterFS client process. @@ -1775,7 +1774,7 @@ File: user-guide.info, Node: Trace, Prev: ROT-13, Up: Miscellaneous Translato The trace translator is intended for debugging purposes. When loaded, it logs all the system calls received by the server or client (wherever trace is loaded), their arguments, and the results. You must -use a GlusterFS log level of DEBUG (See *Note Running GlusterFS::) for +use a GlusterFS log level of DEBUG (See *note Running GlusterFS::) for trace to work. Sample trace output (lines have been wrapped for readability): @@ -2003,7 +2002,7 @@ concludes with the suggested procedure to report bugs in GlusterFS. `/etc/glusterfs/glusterfsd.vol'. The example specification file will be installed as `/etc/glusterfs/glusterfsd.vol.sample'. You need to edit it and rename it, or provide a different specification file using the -`--spec-file' command line option (See *Note Server::). +`--spec-file' command line option (See *note Server::). gf_log_init: failed to open logfile "/usr/var/log/glusterfs/glusterfsd.log" (Permission denied) @@ -2011,7 +2010,7 @@ it and rename it, or provide a different specification file using the You don't have permission to create files in the `/usr/var/log/glusterfs' directory. Make sure you are running GlusterFS as root. Alternatively, specify a different path for the log file using -the `--log-file' option (See *Note Server::). +the `--log-file' option (See *note Server::). 6.1.2 Client errors ------------------- @@ -2052,7 +2051,7 @@ instead. You don't have permission to create files in the `/usr/var/log/glusterfs' directory. Make sure you are running GlusterFS as root. Alternatively, specify a different path for the log file using -the `--log-file' option (See *Note Client::). +the `--log-file' option (See *note Client::). 6.2 FUSE error messages ======================= @@ -2647,52 +2646,52 @@ Index Tag Table: -Node: Top703 -Node: Acknowledgements2303 -Node: Introduction3213 -Node: Installation and Invocation4648 -Node: Pre requisites4932 -Node: Getting GlusterFS7022 -Ref: Getting GlusterFS-Footnote-17808 -Node: Building7856 -Node: Running GlusterFS9558 -Node: Server9769 -Node: Client11357 -Node: A Tutorial Introduction13563 -Node: Concepts17100 -Node: Filesystems in Userspace17315 -Node: Translator18456 -Node: Volume specification file21159 -Node: Translators23631 -Node: Storage Translators24200 -Ref: Storage Translators-Footnote-125007 -Node: POSIX25141 -Node: BDB25764 -Node: Client and Server Translators26821 -Node: Transport modules27297 -Node: Client protocol31444 -Node: Server protocol32383 -Node: Clustering Translators33372 -Node: Unify34259 -Ref: Unify-Footnote-143858 -Node: Replicate43950 -Node: Stripe49005 -Node: Performance Translators50163 -Node: Read Ahead50437 -Node: Write Behind52169 -Node: IO Threads53578 -Node: IO Cache54366 -Node: Booster55690 -Node: Features Translators57104 -Node: POSIX Locks57332 -Node: Fixed ID58649 -Node: Miscellaneous Translators59135 -Node: ROT-1359333 -Node: Trace60012 -Node: Usage Scenarios61281 -Ref: Usage Scenarios-Footnote-167214 -Node: Troubleshooting67289 -Node: GNU Free Documentation Licence73637 -Node: Index96086 +Node: Top704 +Node: Acknowledgements2304 +Node: Introduction3214 +Node: Installation and Invocation4649 +Node: Pre requisites4933 +Node: Getting GlusterFS7023 +Ref: Getting GlusterFS-Footnote-17809 +Node: Building7857 +Node: Running GlusterFS9559 +Node: Server9770 +Node: Client11358 +Node: A Tutorial Introduction13564 +Node: Concepts17101 +Node: Filesystems in Userspace17316 +Node: Translator18457 +Node: Volume specification file21160 +Node: Translators23632 +Node: Storage Translators24201 +Ref: Storage Translators-Footnote-125008 +Node: POSIX25142 +Node: BDB25765 +Node: Client and Server Translators26822 +Node: Transport modules27298 +Node: Client protocol31445 +Node: Server protocol32384 +Node: Clustering Translators33373 +Node: Unify34260 +Ref: Unify-Footnote-143859 +Node: Replicate43951 +Node: Stripe49006 +Node: Performance Translators50164 +Node: Read Ahead50438 +Node: Write Behind52170 +Node: IO Threads53579 +Node: IO Cache54367 +Node: Booster55691 +Node: Features Translators57105 +Node: POSIX Locks57333 +Node: Fixed ID58650 +Node: Miscellaneous Translators59136 +Node: ROT-1359334 +Node: Trace60013 +Node: Usage Scenarios61282 +Ref: Usage Scenarios-Footnote-167215 +Node: Troubleshooting67290 +Node: GNU Free Documentation Licence73638 +Node: Index96087 End Tag Table diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c index 1f825286ec6..1c2931240d5 100644 --- a/xlators/cluster/afr/src/afr-transaction.c +++ b/xlators/cluster/afr/src/afr-transaction.c @@ -887,6 +887,8 @@ int afr_lock_rec (call_frame_t *frame, xlator_t *this, int child_index) int32_t afr_lock (call_frame_t *frame, xlator_t *this) { + frame->root->pid = frame->root; + return afr_lock_rec (frame, this, 0); } diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index bdabb1511bb..d87aec229ed 100644 --- a/xlators/features/locks/src/common.c +++ b/xlators/features/locks/src/common.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com> + Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> This file is part of GlusterFS. GlusterFS is free software; you can redistribute it and/or modify @@ -37,53 +37,51 @@ #include "locks.h" -int -pl_is_lock_grantable (pl_inode_t *pl_inode, posix_lock_t *lock, - gf_lk_domain_t dom); +static int +__is_lock_grantable (pl_inode_t *pl_inode, posix_lock_t *lock, + gf_lk_domain_t dom); static void __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock, gf_lk_domain_t dom); +#define DOMAIN_HEAD(pl_inode, dom) (dom == GF_LOCK_POSIX \ + ? &pl_inode->ext_list \ + : &pl_inode->int_list) pl_inode_t * pl_inode_get (xlator_t *this, inode_t *inode) { - pl_inode_t *pl_inode = NULL; - mode_t st_mode = 0; - uint64_t tmp_pl_inode = 0; - int ret = 0; - - LOCK (&inode->lock); - { - ret = inode_ctx_get (inode, this, &tmp_pl_inode); - if (ret == 0) { - pl_inode = (pl_inode_t *)(long)tmp_pl_inode; - goto out; - } + pl_inode_t *pl_inode = NULL; + mode_t st_mode = 0; + int ret = 0; + + ret = inode_ctx_get (inode, this, + (uint64_t *)(&pl_inode)); + if (ret == 0) + goto out; + + pl_inode = CALLOC (1, sizeof (*pl_inode)); + if (!pl_inode) { + gf_log (this->name, GF_LOG_ERROR, + "out of memory :("); + goto out; + } - pl_inode = CALLOC (1, sizeof (*pl_inode)); - if (!pl_inode) { - gf_log (this->name, GF_LOG_ERROR, - "out of memory :("); - goto out; - } + st_mode = inode->st_mode; + if ((st_mode & S_ISGID) && !(st_mode & S_IXGRP)) + pl_inode->mandatory = 1; - st_mode = inode->st_mode; - if ((st_mode & S_ISGID) && !(st_mode & S_IXGRP)) - pl_inode->mandatory = 1; + pthread_mutex_init (&pl_inode->mutex, NULL); - pthread_mutex_init (&pl_inode->mutex, NULL); - - INIT_LIST_HEAD (&pl_inode->dir_list); - INIT_LIST_HEAD (&pl_inode->ext_list); - INIT_LIST_HEAD (&pl_inode->int_list); - INIT_LIST_HEAD (&pl_inode->rw_list); + INIT_LIST_HEAD (&pl_inode->dir_list); + INIT_LIST_HEAD (&pl_inode->ext_list); + INIT_LIST_HEAD (&pl_inode->int_list); + INIT_LIST_HEAD (&pl_inode->rw_list); + + ret = inode_ctx_put (inode, this, (uint64_t)(long)(pl_inode)); - ret = inode_ctx_put (inode, this, (uint64_t)(long)pl_inode); - } out: - UNLOCK (&inode->lock); return pl_inode; } @@ -148,8 +146,8 @@ posix_lock_to_flock (posix_lock_t *lock, struct flock *flock) /* Insert the lock into the inode's lock list */ -void -pl_insert_lock (pl_inode_t *pl_inode, posix_lock_t *lock, gf_lk_domain_t dom) +static void +__insert_lock (pl_inode_t *pl_inode, posix_lock_t *lock, gf_lk_domain_t dom) { list_add_tail (&lock->list, DOMAIN_HEAD (pl_inode, dom)); @@ -305,9 +303,9 @@ first_overlap (pl_inode_t *pl_inode, posix_lock_t *lock, /* Return true if lock is grantable */ -int -pl_is_lock_grantable (pl_inode_t *pl_inode, posix_lock_t *lock, - gf_lk_domain_t dom) +static int +__is_lock_grantable (pl_inode_t *pl_inode, posix_lock_t *lock, + gf_lk_domain_t dom) { posix_lock_t *l = NULL; int ret = 1; @@ -398,14 +396,14 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock, } if ((conf->fl_type == F_RDLCK) && (lock->fl_type == F_RDLCK)) { - pl_insert_lock (pl_inode, lock, dom); + __insert_lock (pl_inode, lock, dom); return; } } /* no conflicts, so just insert */ if (lock->fl_type != F_UNLCK) { - pl_insert_lock (pl_inode, lock, dom); + __insert_lock (pl_inode, lock, dom); } else { __destroy_lock (lock); } @@ -437,12 +435,12 @@ __grant_blocked_locks (xlator_t *this, pl_inode_t *pl_inode, list_for_each_entry_safe (l, tmp, &tmp_list, list) { list_del_init (&l->list); - if (pl_is_lock_grantable (pl_inode, l, dom)) { + if (__is_lock_grantable (pl_inode, l, dom)) { conf = CALLOC (1, sizeof (*conf)); if (!conf) { l->blocked = 1; - pl_insert_lock (pl_inode, l, dom); + __insert_lock (pl_inode, l, dom); continue; } @@ -463,7 +461,7 @@ __grant_blocked_locks (xlator_t *this, pl_inode_t *pl_inode, list_add (&conf->list, granted); } else { l->blocked = 1; - pl_insert_lock (pl_inode, l, dom); + __insert_lock (pl_inode, l, dom); } } } @@ -506,7 +504,7 @@ pl_setlk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, pthread_mutex_lock (&pl_inode->mutex); { - if (pl_is_lock_grantable (pl_inode, lock, dom)) { + if (__is_lock_grantable (pl_inode, lock, dom)) { gf_log (this->name, GF_LOG_DEBUG, "%s (pid=%d) %"PRId64" - %"PRId64" => OK", lock->fl_type == F_UNLCK ? "Unlock" : "Lock", @@ -522,7 +520,7 @@ pl_setlk (xlator_t *this, pl_inode_t *pl_inode, posix_lock_t *lock, lock->user_flock.l_start, lock->user_flock.l_len); lock->blocked = 1; - pl_insert_lock (pl_inode, lock, dom); + __insert_lock (pl_inode, lock, dom); ret = -1; } else { gf_log (this->name, GF_LOG_DEBUG, diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h index 45d0670e912..ee17b008737 100644 --- a/xlators/features/locks/src/common.h +++ b/xlators/features/locks/src/common.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com> + Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> This file is part of GlusterFS. GlusterFS is free software; you can redistribute it and/or modify @@ -33,13 +33,6 @@ int pl_setlk (xlator_t *this, pl_inode_t *inode, posix_lock_t *lock, int can_block, gf_lk_domain_t domain); -int -pl_is_lock_grantable (pl_inode_t *pl_inode, posix_lock_t *lock, - gf_lk_domain_t dom); - -void -pl_insert_lock (pl_inode_t *pl_inode, posix_lock_t *lock, gf_lk_domain_t dom); - void grant_blocked_locks (xlator_t *this, pl_inode_t *inode, gf_lk_domain_t domain); diff --git a/xlators/features/locks/src/internal.c b/xlators/features/locks/src/internal.c index eb3862fe963..985762fb9eb 100644 --- a/xlators/features/locks/src/internal.c +++ b/xlators/features/locks/src/internal.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com> + Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> This file is part of GlusterFS. GlusterFS is free software; you can redistribute it and/or modify @@ -52,24 +52,6 @@ delete_locks_of_transport (pl_inode_t *pinode, transport_t *trans) } -static posix_lock_t * -__find_exact_matching_lock (pl_inode_t *pinode, posix_lock_t *lock) -{ - posix_lock_t *l = NULL; - posix_lock_t *match = NULL; - - list_for_each_entry (l, DOMAIN_HEAD (pinode, GF_LOCK_INTERNAL), list) { - if (same_owner (l, lock) - && (l->fl_start == lock->fl_start) - && (l->fl_end == lock->fl_end)) { - match = l; - break; - } - } - - return match; -} - /** * pl_inodelk: * @@ -78,26 +60,23 @@ __find_exact_matching_lock (pl_inode_t *pinode, posix_lock_t *lock) * from those held by applications. This fop is for the use of AFR. */ - -static int -pl_inodelk_common (call_frame_t *frame, xlator_t *this, - inode_t *inode, int32_t cmd, struct flock *flock) +int +pl_inodelk (call_frame_t *frame, xlator_t *this, + loc_t *loc, int32_t cmd, struct flock *flock) { int32_t op_ret = -1; int32_t op_errno = 0; + int ret = -1; int can_block = 0; - posix_locks_private_t * priv = NULL; transport_t * transport = NULL; pid_t client_pid = -1; pl_inode_t * pinode = NULL; - posix_lock_t * reqlock = NULL; - posix_lock_t * matchlock = NULL; /* steady, fire! */ - VALIDATE_OR_GOTO (frame, unwind); - VALIDATE_OR_GOTO (inode, unwind); - VALIDATE_OR_GOTO (flock, unwind); + VALIDATE_OR_GOTO (frame, out); + VALIDATE_OR_GOTO (loc, out); + VALIDATE_OR_GOTO (flock, out); if ((flock->l_start < 0) || (flock->l_len < 0)) { op_errno = EINVAL; @@ -109,9 +88,9 @@ pl_inodelk_common (call_frame_t *frame, xlator_t *this, priv = (posix_locks_private_t *) this->private; - VALIDATE_OR_GOTO (priv, unwind); + VALIDATE_OR_GOTO (priv, out); - pinode = pl_inode_get (this, inode); + pinode = pl_inode_get (this, loc->inode); if (!pinode) { gf_log (this->name, GF_LOG_ERROR, "out of memory :("); @@ -124,7 +103,6 @@ pl_inodelk_common (call_frame_t *frame, xlator_t *this, special case: this means release all locks from this transport */ - gf_log (this->name, GF_LOG_DEBUG, "releasing all locks from transport %p", transport); @@ -141,117 +119,145 @@ pl_inodelk_common (call_frame_t *frame, xlator_t *this, goto unwind; } - pthread_mutex_lock (&pinode->mutex); - { - switch (cmd) { - case F_SETLKW: - can_block = 1; - reqlock->frame = frame; - reqlock->this = this; - - /* fall through */ - - case F_SETLK: - memcpy (&reqlock->user_flock, flock, sizeof (struct flock)); - - switch (flock->l_type) { - - case F_WRLCK: - if (!pl_is_lock_grantable (pinode, reqlock, GF_LOCK_INTERNAL)) { - if (can_block) { - gf_log (this->name, GF_LOG_DEBUG, - "%s (pid=%d) %"PRId64" - %"PRId64" => blocked", - reqlock->fl_type == F_UNLCK ? "unlock" : "lock", - reqlock->client_pid, - reqlock->user_flock.l_start, - reqlock->user_flock.l_len); - pl_insert_lock (pinode, reqlock, GF_LOCK_INTERNAL); - - goto unlock; - } - - __destroy_lock (reqlock); - - - gf_log (this->name, GF_LOG_DEBUG, - "%s (pid=%d) %"PRId64" - %"PRId64" => NOK", - reqlock->fl_type == F_UNLCK ? "unlock" : "lock", - reqlock->client_pid, reqlock->user_flock.l_start, - reqlock->user_flock.l_len); - op_errno = EAGAIN; - - goto unlock; - } - - gf_log (this->name, GF_LOG_DEBUG, - "%s (pid=%d) %"PRId64" - %"PRId64" => OK", - reqlock->fl_type == F_UNLCK ? "unlock" : "lock", - reqlock->client_pid, - reqlock->user_flock.l_start, - reqlock->user_flock.l_len); - pl_insert_lock (pinode, reqlock, GF_LOCK_INTERNAL); - - break; - - case F_UNLCK: - matchlock = __find_exact_matching_lock (pinode, reqlock); - - __destroy_lock (reqlock); - if (!matchlock) { - op_errno = EINVAL; - goto unlock; - } - - __delete_lock (pinode, matchlock); - __destroy_lock (matchlock); - - break; - - default: - op_errno = ENOTSUP; - gf_log (this->name, GF_LOG_ERROR, - "lock type %d not supported for [F]INODELK", - flock->l_type); - goto unlock; - } - - - break; - - default: - op_errno = ENOTSUP; - gf_log (this->name, GF_LOG_ERROR, - "lock command F_GETLK not supported for [F]INODELK (cmd=%d)", - cmd); - goto unlock; + switch (cmd) { + case F_SETLKW: + can_block = 1; + reqlock->frame = frame; + reqlock->this = this; + + /* fall through */ + + case F_SETLK: + memcpy (&reqlock->user_flock, flock, sizeof (struct flock)); + ret = pl_setlk (this, pinode, reqlock, + can_block, GF_LOCK_INTERNAL); + + if (ret == -1) { + if (can_block) + goto out; + + gf_log (this->name, GF_LOG_DEBUG, "returning EAGAIN"); + op_errno = EAGAIN; + __destroy_lock (reqlock); + goto unwind; } - - op_ret = 0; - - unlock: - if (pinode) - pthread_mutex_unlock (&pinode->mutex); + break; + + default: + op_errno = ENOTSUP; + gf_log (this->name, GF_LOG_ERROR, + "lock command F_GETLK not supported for GF_FILE_LK (cmd=%d)", + cmd); + goto unwind; } -unwind: + op_ret = 0; + +unwind: STACK_UNWIND (frame, op_ret, op_errno); +out: return 0; } int -pl_inodelk (call_frame_t *frame, xlator_t *this, - loc_t *loc, int32_t cmd, struct flock *flock) -{ - return pl_inodelk_common (frame, this, loc->inode, cmd, flock); -} - - -int pl_finodelk (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t cmd, struct flock *flock) { - return pl_inodelk_common (frame, this, fd->inode, cmd, flock); + int32_t op_ret = -1; + int32_t op_errno = 0; + int ret = -1; + int can_block = 0; + posix_locks_private_t * priv = NULL; + transport_t * transport = NULL; + pid_t client_pid = -1; + pl_inode_t * pinode = NULL; + posix_lock_t * reqlock = NULL; + + VALIDATE_OR_GOTO (frame, out); + VALIDATE_OR_GOTO (fd, out); + VALIDATE_OR_GOTO (flock, out); + + if ((flock->l_start < 0) || (flock->l_len < 0)) { + op_errno = EINVAL; + goto unwind; + } + + transport = frame->root->trans; + client_pid = frame->root->pid; + + priv = (posix_locks_private_t *) this->private; + + VALIDATE_OR_GOTO (priv, out); + + pinode = pl_inode_get (this, fd->inode); + if (!pinode) { + gf_log (this->name, GF_LOG_ERROR, + "out of memory :("); + op_errno = ENOMEM; + goto unwind; + } + + if (client_pid == 0) { + /* + special case: this means release all locks + from this transport + */ + gf_log (this->name, GF_LOG_DEBUG, + "releasing all locks from transport %p", transport); + + delete_locks_of_transport (pinode, transport); + goto unwind; + } + + reqlock = new_posix_lock (flock, transport, client_pid); + if (!reqlock) { + gf_log (this->name, GF_LOG_ERROR, + "out of memory :("); + op_ret = -1; + op_errno = ENOMEM; + goto unwind; + } + + switch (cmd) { + case F_SETLKW: + can_block = 1; + reqlock->frame = frame; + reqlock->this = this; + reqlock->fd = fd; + + /* fall through */ + + case F_SETLK: + memcpy (&reqlock->user_flock, flock, sizeof (struct flock)); + ret = pl_setlk (this, pinode, reqlock, + can_block, GF_LOCK_INTERNAL); + + if (ret == -1) { + if (can_block) + goto out; + + gf_log (this->name, GF_LOG_DEBUG, "returning EAGAIN"); + op_errno = EAGAIN; + __destroy_lock (reqlock); + goto unwind; + } + break; + + default: + op_errno = ENOTSUP; + gf_log (this->name, GF_LOG_ERROR, + "lock command F_GETLK not supported for GF_FILE_LK (cmd=%d)", + cmd); + goto unwind; + } + + op_ret = 0; + +unwind: + STACK_UNWIND (frame, op_ret, op_errno); +out: + return 0; } @@ -642,9 +648,9 @@ unlock: */ int -pl_entrylk_common (call_frame_t *frame, xlator_t *this, - inode_t *inode, const char *basename, - entrylk_cmd cmd, entrylk_type type) +pl_entrylk (call_frame_t *frame, xlator_t *this, + loc_t *loc, const char *basename, + entrylk_cmd cmd, entrylk_type type) { int32_t op_ret = -1; int32_t op_errno = 0; @@ -657,7 +663,8 @@ pl_entrylk_common (call_frame_t *frame, xlator_t *this, pl_entry_lock_t *unlocked = NULL; char unwind = 1; - pinode = pl_inode_get (this, inode); + + pinode = pl_inode_get (this, loc->inode); if (!pinode) { gf_log (this->name, GF_LOG_ERROR, "out of memory :("); @@ -744,19 +751,105 @@ out: } -int -pl_entrylk (call_frame_t *frame, xlator_t *this, - loc_t *loc, const char *basename, - entrylk_cmd cmd, entrylk_type type) -{ - return pl_entrylk_common (frame, this, loc->inode, basename, cmd, type); -} - +/** + * pl_entrylk: + * + * Locking on names (directory entries) + */ int pl_fentrylk (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *basename, entrylk_cmd cmd, entrylk_type type) { - return pl_entrylk_common (frame, this, fd->inode, basename, cmd, type); + int32_t op_ret = -1; + int32_t op_errno = 0; + + transport_t * transport = NULL; + pid_t pid = -1; + + pl_inode_t * pinode = NULL; + int ret = -1; + pl_entry_lock_t *unlocked = NULL; + char unwind = 1; + + pinode = pl_inode_get (this, fd->inode); + if (!pinode) { + gf_log (this->name, GF_LOG_ERROR, + "out of memory :("); + goto out; + } + + pid = frame->root->pid; + transport = frame->root->trans; + + if (pid == 0) { + /* + this is a special case that means release + all locks from this transport + */ + + gf_log (this->name, GF_LOG_DEBUG, + "releasing locks for transport %p", transport); + + release_entry_locks_for_transport (this, pinode, transport); + op_ret = 0; + goto out; + } + + switch (cmd) { + case ENTRYLK_LOCK: + pthread_mutex_lock (&pinode->mutex); + { + ret = __lock_name (pinode, basename, type, + frame, this, 0); + } + pthread_mutex_unlock (&pinode->mutex); + + if (ret < 0) { + if (ret == -EAGAIN) + unwind = 0; + op_errno = -ret; + goto out; + } + break; + + case ENTRYLK_LOCK_NB: + pthread_mutex_lock (&pinode->mutex); + { + ret = __lock_name (pinode, basename, type, + frame, this, 1); + } + pthread_mutex_unlock (&pinode->mutex); + + if (ret < 0) { + op_errno = -ret; + goto out; + } + break; + + case ENTRYLK_UNLOCK: + pthread_mutex_lock (&pinode->mutex); + { + unlocked = __unlock_name (pinode, basename, type); + } + pthread_mutex_unlock (&pinode->mutex); + + if (unlocked) + grant_blocked_entry_locks (this, pinode, unlocked); + break; + + default: + gf_log (this->name, GF_LOG_ERROR, + "unexpected case!"); + goto out; + } + + op_ret = 0; +out: + if (unwind) { + STACK_UNWIND (frame, op_ret, op_errno); + } + + return 0; } diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h index b62b13a7130..5a834657d0b 100644 --- a/xlators/features/locks/src/locks.h +++ b/xlators/features/locks/src/locks.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com> + Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> This file is part of GlusterFS. GlusterFS is free software; you can redistribute it and/or modify @@ -92,10 +92,10 @@ struct __pl_inode { }; typedef struct __pl_inode pl_inode_t; -#define DOMAIN_HEAD(pl_inode, dom) (dom == GF_LOCK_POSIX \ - ? &pl_inode->ext_list \ - : &pl_inode->int_list) +#define LOCKS_FOR_DOMAIN(inode,domain) (domain == GF_LOCK_POSIX \ + ? inode->fcntl_locks \ + : inode->inodelk_locks) struct __pl_fd { gf_boolean_t nonblocking; /* whether O_NONBLOCK has been set */ diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index c2fee4d5838..46d2cb9a003 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2006-2009 Z RESEARCH, Inc. <http://www.zresearch.com> + Copyright (c) 2006, 2007, 2008 Z RESEARCH, Inc. <http://www.zresearch.com> This file is part of GlusterFS. GlusterFS is free software; you can redistribute it and/or modify @@ -277,6 +277,7 @@ pl_flush (call_frame_t *frame, xlator_t *this, priv = this->private; pl_inode = pl_inode_get (this, fd->inode); + if (!pl_inode) { gf_log (this->name, GF_LOG_ERROR, "returning EBADFD"); STACK_UNWIND (frame, -1, EBADFD); @@ -443,7 +444,6 @@ pl_readv (call_frame_t *frame, xlator_t *this, priv = this->private; - pl_inode = pl_inode_get (this, fd->inode); if (priv->mandatory && pl_inode->mandatory) { @@ -537,8 +537,8 @@ pl_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, priv = this->private; - pl_inode = pl_inode_get (this, fd->inode); + if (priv->mandatory && pl_inode->mandatory) { region.fl_start = offset; region.fl_end = offset + iov_length (vector, count) - 1; @@ -719,7 +719,7 @@ pl_forget (xlator_t *this, "Pending entry locks found!"); } - FREE (pl_inode); + FREE (pl_inode); return 0; } |