nfs-ganesha 1.4
|
00001 /* 00002 * Copyright IBM Corporation, 2010 00003 * Contributor: Aneesh Kumar K.v <aneesh.kumar@linux.vnet.ibm.com> 00004 * 00005 * 00006 * This software is a server that implements the NFS protocol. 00007 * 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 3 of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 * 00024 */ 00025 #ifdef HAVE_CONFIG_H 00026 #include "config.h" 00027 #endif 00028 00029 #include "fsal.h" 00030 #include "fsal_internal.h" 00031 #include "fsal_convert.h" 00032 00062 fsal_status_t GPFSFSAL_lock_op( fsal_file_t * p_file_descriptor, /* IN */ 00063 fsal_handle_t * p_filehandle, /* IN */ 00064 fsal_op_context_t * p_context, /* IN */ 00065 void * p_owner, /* IN */ 00066 fsal_lock_op_t lock_op, /* IN */ 00067 fsal_lock_param_t request_lock, /* IN */ 00068 fsal_lock_param_t * conflicting_lock) /* OUT */ 00069 { 00070 int retval; 00071 struct glock glock_args; 00072 struct set_get_lock_arg gpfs_sg_arg; 00073 glock_args.lfd = ((gpfsfsal_file_t *)p_file_descriptor)->fd; 00074 gpfsfsal_op_context_t *gpfs_op_cxt = (gpfsfsal_op_context_t *)p_context; 00075 gpfsfsal_file_t * pfd = (gpfsfsal_file_t *) p_file_descriptor; 00076 00077 if(p_file_descriptor == NULL) 00078 { 00079 LogDebug(COMPONENT_FSAL, "p_file_descriptor arg is NULL."); 00080 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op); 00081 } 00082 if(p_filehandle == NULL) 00083 { 00084 LogDebug(COMPONENT_FSAL, "p_filehandle arg is NULL."); 00085 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op); 00086 } 00087 if(p_context == NULL) 00088 { 00089 LogDebug(COMPONENT_FSAL, "p_context arg is NULL."); 00090 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op); 00091 } 00092 if(p_owner == NULL) 00093 { 00094 LogDebug(COMPONENT_FSAL, "p_owner arg is NULL."); 00095 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op); 00096 } 00097 00098 if(conflicting_lock == NULL && lock_op == FSAL_OP_LOCKT) 00099 { 00100 LogDebug(COMPONENT_FSAL, 00101 "Conflicting_lock argument can't be NULL with lock_op = LOCKT"); 00102 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op); 00103 } 00104 00105 LogFullDebug(COMPONENT_FSAL, 00106 "Locking: op:%d type:%d start:%llu length:%llu owner:%p", 00107 lock_op, request_lock.lock_type, 00108 (unsigned long long)request_lock.lock_start, 00109 (unsigned long long)request_lock.lock_length, p_owner); 00110 00111 if(lock_op == FSAL_OP_LOCKT) 00112 glock_args.cmd = F_GETLK; 00113 else if(lock_op == FSAL_OP_LOCK || lock_op == FSAL_OP_UNLOCK) 00114 glock_args.cmd = F_SETLK; 00115 else if(lock_op == FSAL_OP_LOCKB) 00116 glock_args.cmd = F_SETLKW; 00117 else if(lock_op == FSAL_OP_CANCEL) 00118 glock_args.cmd = 1029; // TODO FSF: hack - replace with GPFS_F_CANCELLK; 00119 else 00120 { 00121 LogDebug(COMPONENT_FSAL, 00122 "ERROR: Lock operation requested was not TEST, GET, or SET."); 00123 Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op); 00124 } 00125 00126 if(request_lock.lock_type == FSAL_LOCK_R) 00127 glock_args.flock.l_type = F_RDLCK; 00128 else if(request_lock.lock_type == FSAL_LOCK_W) 00129 glock_args.flock.l_type = F_WRLCK; 00130 else 00131 { 00132 LogDebug(COMPONENT_FSAL, 00133 "ERROR: The requested lock type was not read or write."); 00134 Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op); 00135 } 00136 00137 if(lock_op == FSAL_OP_UNLOCK) 00138 glock_args.flock.l_type = F_UNLCK; 00139 00140 glock_args.flock.l_len = request_lock.lock_length; 00141 glock_args.flock.l_start = request_lock.lock_start; 00142 glock_args.flock.l_whence = SEEK_SET; 00143 00144 glock_args.lfd = pfd->fd; 00145 glock_args.lock_owner = p_owner; 00146 gpfs_sg_arg.mountdirfd = gpfs_op_cxt->export_context->mount_root_fd; 00147 gpfs_sg_arg.lock = &glock_args; 00148 00149 errno = 0; 00150 00151 retval = gpfs_ganesha(lock_op == FSAL_OP_LOCKT ? 00152 OPENHANDLE_GET_LOCK : OPENHANDLE_SET_LOCK, &gpfs_sg_arg); 00153 00154 if(retval) 00155 { 00156 int errsv = errno; 00157 00158 if((conflicting_lock != NULL) && 00159 (lock_op == FSAL_OP_LOCK || lock_op == FSAL_OP_LOCKB)) 00160 { 00161 int retval2; 00162 glock_args.cmd = F_GETLK; 00163 retval2 = gpfs_ganesha(OPENHANDLE_GET_LOCK, &gpfs_sg_arg); 00164 if(retval2) 00165 { 00166 LogCrit(COMPONENT_FSAL, 00167 "After failing a set lock request, An attempt to get the current owner details also failed."); 00168 } 00169 else 00170 { 00171 conflicting_lock->lock_length = glock_args.flock.l_len; 00172 conflicting_lock->lock_start = glock_args.flock.l_start; 00173 conflicting_lock->lock_type = glock_args.flock.l_type; 00174 } 00175 } 00176 if(retval == 1) 00177 { 00178 LogFullDebug(COMPONENT_FSAL, 00179 "GPFS queued blocked lock"); 00180 Return(ERR_FSAL_BLOCKED, 0, INDEX_FSAL_lock_op); 00181 } 00182 else 00183 { 00184 LogFullDebug(COMPONENT_FSAL, 00185 "GPFS lock operation failed error %d %d (%s)", 00186 retval, errsv, strerror(errsv)); 00187 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lock_op); 00188 } 00189 } 00190 00191 /* F_UNLCK is returned then the tested operation would be possible. */ 00192 if(conflicting_lock != NULL) 00193 { 00194 if(lock_op == FSAL_OP_LOCKT && glock_args.flock.l_type != F_UNLCK) 00195 { 00196 conflicting_lock->lock_length = glock_args.flock.l_len; 00197 conflicting_lock->lock_start = glock_args.flock.l_start; 00198 conflicting_lock->lock_type = glock_args.flock.l_type; 00199 } 00200 else 00201 { 00202 conflicting_lock->lock_length = 0; 00203 conflicting_lock->lock_start = 0; 00204 conflicting_lock->lock_type = FSAL_NO_LOCK; 00205 } 00206 } 00207 00208 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lock_op); 00209 }