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 VFSFSAL_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 (opaque to FSAL) */ 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 flock lock_args; 00072 int fcntl_comm; 00073 vfsfsal_file_t * pfd = (vfsfsal_file_t *) p_file_descriptor; 00074 00075 if(p_file_descriptor == NULL || p_filehandle == NULL || p_context == NULL) 00076 { 00077 if(p_file_descriptor == NULL) 00078 LogDebug(COMPONENT_FSAL, "p_file_descriptor argument is NULL."); 00079 if(p_filehandle == NULL) 00080 LogDebug(COMPONENT_FSAL, "p_filehandle argument is NULL."); 00081 if(p_context == NULL) 00082 LogDebug(COMPONENT_FSAL, "p_context argument is NULL."); 00083 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op); 00084 } 00085 00086 if(p_owner != NULL) 00087 Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op); 00088 00089 if(conflicting_lock == NULL && lock_op == FSAL_OP_LOCKT) 00090 { 00091 LogDebug(COMPONENT_FSAL, "conflicting_lock argument can't" 00092 " be NULL with lock_op = LOCKT"); 00093 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lock_op); 00094 } 00095 00096 LogFullDebug(COMPONENT_FSAL, "Locking: op:%d type:%d start:%"PRIu64" length:%zu ", lock_op, 00097 request_lock.lock_type, request_lock.lock_start, request_lock.lock_length); 00098 00099 if(lock_op == FSAL_OP_LOCKT) 00100 fcntl_comm = F_GETLK; 00101 else if(lock_op == FSAL_OP_LOCK || lock_op == FSAL_OP_UNLOCK) 00102 fcntl_comm = F_SETLK; 00103 else 00104 { 00105 LogDebug(COMPONENT_FSAL, "ERROR: Lock operation requested was not TEST, READ, or WRITE."); 00106 Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op); 00107 } 00108 00109 if(request_lock.lock_type == FSAL_LOCK_R) 00110 lock_args.l_type = F_RDLCK; 00111 else if(request_lock.lock_type == FSAL_LOCK_W) 00112 lock_args.l_type = F_WRLCK; 00113 else 00114 { 00115 LogDebug(COMPONENT_FSAL, "ERROR: The requested lock type was not read or write."); 00116 Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_lock_op); 00117 } 00118 00119 if(lock_op == FSAL_OP_UNLOCK) 00120 lock_args.l_type = F_UNLCK; 00121 00122 lock_args.l_len = request_lock.lock_length; 00123 lock_args.l_start = request_lock.lock_start; 00124 lock_args.l_whence = SEEK_SET; 00125 00126 errno = 0; 00127 retval = fcntl(pfd->fd, fcntl_comm, &lock_args); 00128 if(retval && lock_op == FSAL_OP_LOCK) 00129 { 00130 if(conflicting_lock != NULL) 00131 { 00132 fcntl_comm = F_GETLK; 00133 retval = fcntl(pfd->fd, fcntl_comm, &lock_args); 00134 if(retval) 00135 { 00136 LogCrit(COMPONENT_FSAL, "After failing a lock request, I couldn't even" 00137 " get the details of who owns the lock."); 00138 Return(posix2fsal_error(errno), errno, INDEX_FSAL_lock_op); 00139 } 00140 if(conflicting_lock != NULL) 00141 { 00142 conflicting_lock->lock_length = lock_args.l_len; 00143 conflicting_lock->lock_start = lock_args.l_start; 00144 conflicting_lock->lock_type = lock_args.l_type; 00145 } 00146 } 00147 Return(posix2fsal_error(errno), errno, INDEX_FSAL_lock_op); 00148 } 00149 00150 /* F_UNLCK is returned then the tested operation would be possible. */ 00151 if(conflicting_lock != NULL) 00152 { 00153 if(lock_op == FSAL_OP_LOCKT && lock_args.l_type != F_UNLCK) 00154 { 00155 conflicting_lock->lock_length = lock_args.l_len; 00156 conflicting_lock->lock_start = lock_args.l_start; 00157 conflicting_lock->lock_type = lock_args.l_type; 00158 } 00159 else 00160 { 00161 conflicting_lock->lock_length = 0; 00162 conflicting_lock->lock_start = 0; 00163 conflicting_lock->lock_type = FSAL_NO_LOCK; 00164 } 00165 } 00166 00167 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lock_op); 00168 }