XrdOssUnlink.cc

Go to the documentation of this file.
00001 /******************************************************************************/
00002 /*                                                                            */
00003 /*                       X r d O s s U n l i n k . c c                        */
00004 /*                                                                            */
00005 /* (c) 2003 by the Board of Trustees of the Leland Stanford, Jr., University  */
00006 /*                            All Rights Reserved                             */
00007 /*   Produced by Andrew Hanushevsky for Stanford University under contract    */
00008 /*              DE-AC03-76-SFO0515 with the Department of Energy              */
00009 /******************************************************************************/
00010 
00011 //         $Id: XrdOssUnlink.cc 34000 2010-06-21 06:49:56Z ganis $
00012 
00013 const char *XrdOssUnlinkCVSID = "$Id: XrdOssUnlink.cc 34000 2010-06-21 06:49:56Z ganis $";
00014 
00015 #include <unistd.h>
00016 #include <errno.h>
00017 #include <strings.h>
00018 #include <limits.h>
00019 #include <stdio.h>
00020 #include <sys/param.h>
00021 #include <sys/types.h>
00022 #include <sys/stat.h>
00023 
00024 #include "XrdSys/XrdSysHeaders.hh"
00025 #include "XrdOss/XrdOssApi.hh"
00026 #include "XrdOss/XrdOssCache.hh"
00027 #include "XrdOss/XrdOssConfig.hh"
00028 #include "XrdOss/XrdOssError.hh"
00029 #include "XrdOss/XrdOssLock.hh"
00030 #include "XrdOss/XrdOssOpaque.hh"
00031 #include "XrdOss/XrdOssPath.hh"
00032 #include "XrdOss/XrdOssTrace.hh"
00033 
00034 /******************************************************************************/
00035 /*           G l o b a l   E r r o r   R o u t i n g   O b j e c t            */
00036 /******************************************************************************/
00037 
00038 extern XrdSysError OssEroute;
00039 
00040 extern XrdOucTrace OssTrace;
00041   
00042 /******************************************************************************/
00043 /*                                R e m d i r                                 */
00044 /******************************************************************************/
00045   
00046 /*
00047   Function: Delete a directory from the namespace.
00048 
00049   Input:    path      - Is the fully qualified name of the dir to be removed.
00050 
00051   Output:   Returns XrdOssOK upon success and -errno upon failure.
00052 */
00053 int XrdOssSys::Remdir(const char *path, int Opts)
00054 {
00055     unsigned long long opts;
00056     int retc;
00057     struct stat statbuff;
00058     char  local_path[MAXPATHLEN+1+8];
00059 
00060 // Build the right local and remote paths.
00061 //
00062    if (Opts & XRDOSS_isPFN) strcpy(local_path, path);
00063       else {retc = Check_RO(Unlink, opts, path, "deleting ");
00064             if ( (retc = GenLocalPath( path,  local_path))) return retc;
00065            }
00066 
00067 // Check if this path is really a directory
00068 //
00069     if (lstat(local_path, &statbuff)) return (errno == ENOENT ? 0 : -errno);
00070     if ((statbuff.st_mode & S_IFMT) != S_IFDIR) return -ENOTDIR;
00071 
00072 // Complete by calling Unlink()
00073 //
00074     return Unlink(path, Opts);
00075 }
00076 
00077 /******************************************************************************/
00078 /*                                U n l i n k                                 */
00079 /******************************************************************************/
00080 
00081 /*
00082   Function: Delete a file from the namespace and release it's data storage.
00083 
00084   Input:    path      - Is the fully qualified name of the file to be removed.
00085 
00086   Output:   Returns XrdOssOK upon success and -errno upon failure.
00087 */
00088 int XrdOssSys::Unlink(const char *path, int Opts)
00089 {
00090     EPNAME("Unlink")
00091     unsigned long long haslf, remotefs;
00092     int i, retc2, doAdjust = 0, retc = XrdOssOK;
00093     XrdOssLock un_file;
00094     struct stat statbuff;
00095     char *fnp;
00096     char  local_path[MAXPATHLEN+1+8];
00097     char remote_path[MAXPATHLEN+1];
00098 
00099 // Build the right local and remote paths.
00100 //
00101    if (Opts & XRDOSS_isPFN)
00102       {strcpy(local_path, path),
00103        *remote_path = '\0';
00104        haslf = Opts & XRDOSS_isMIG;
00105        remotefs = 0;
00106       } else {
00107        remotefs = Check_RO(Unlink, haslf, path, "deleting ");
00108        if ( (retc = GenLocalPath( path,  local_path))
00109        ||   (retc = GenRemotePath(path, remote_path)) ) return retc;
00110        haslf &= XRDEXP_MAKELF;
00111       }
00112 
00113  // Serialize the directory.
00114  //
00115     if (remotefs && (retc=un_file.Serialize(local_path,XrdOssDIR|XrdOssEXC)) < 0)
00116        return retc;
00117 
00118 // Check if this path is really a directory of a symbolic link elsewhere
00119 //
00120     if (lstat(local_path, &statbuff)) retc = (errno == ENOENT ? 0 : -errno);
00121        else if ((statbuff.st_mode & S_IFMT) == S_IFLNK)
00122                retc = BreakLink(local_path, statbuff);
00123                else if ((statbuff.st_mode & S_IFMT) == S_IFDIR)
00124                        {if (remotefs) un_file.UnSerialize(0);
00125                         un_file.NoSerialize(local_path, XrdOssDIR);
00126                         if ((retc = rmdir(local_path))) retc = -errno;
00127                         DEBUG("dir rc=" <<retc <<" path=" <<local_path);
00128                         return retc;
00129                        } else doAdjust = 1;
00130 
00131 // Delete the local copy and every valid suffix variation
00132 //
00133    if (!retc)
00134       {if (unlink(local_path)) retc = -errno;
00135           else {i = strlen(local_path); fnp = &local_path[i];
00136                 if (doAdjust && statbuff.st_size)
00137                    XrdOssCache::Adjust(statbuff.st_dev, -statbuff.st_size);
00138                 if (haslf) for (i = 0; i < XrdOssPath::sfxMigL; i++)
00139                    {strcpy(fnp, XrdOssPath::Sfx[i]);
00140                     if (unlink(local_path))
00141                        if (errno == ENOENT) continue;
00142                           else retc2 = errno;
00143                        else retc2 = 0;
00144                     DEBUG("sfx retc=" <<retc2 <<' ' <<local_path);
00145                    }
00146                }
00147        DEBUG("lcl rc=" <<retc <<" path=" <<local_path);
00148       }
00149 
00150 // If local copy effectively deleted. delete the remote copy if need be
00151 //
00152    if (remotefs && !(Opts & XRDOSS_Online) 
00153    && (!retc || retc == -ENOENT) && RSSCmd)
00154       {if ((retc2 = MSS_Unlink(remote_path)) != -ENOENT) retc = retc2;
00155        DEBUG("rmt rc=" <<retc2 <<" path=" <<remote_path);
00156       }
00157 
00158 // Deserialize the directory and return
00159 //
00160    if (remotefs) un_file.UnSerialize(0);
00161    return retc;
00162 }
00163 
00164 /******************************************************************************/
00165 /*                       P r i v a t e   M e t h o d s                        */
00166 /******************************************************************************/
00167 /******************************************************************************/
00168 /*                             B r e a k L i n k                              */
00169 /******************************************************************************/
00170 
00171 int XrdOssSys::BreakLink(const char *local_path, struct stat &statbuff)
00172 {
00173     EPNAME("BreakLink")
00174     char *lP, lnkbuff[MAXPATHLEN+64];
00175     int lnklen, retc = 0;
00176 
00177 // Read the contents of the link
00178 //
00179     if ((lnklen = readlink(local_path, lnkbuff, sizeof(lnkbuff)-1)) < 0)
00180        return -errno;
00181 
00182 // Return the actual stat information on the target (which might not exist
00183 //
00184    lnkbuff[lnklen] = '\0';
00185    if (stat(lnkbuff, &statbuff)) statbuff.st_size = 0;
00186       else if (unlink(lnkbuff) && errno != ENOENT)
00187               {retc = -errno;
00188                OssEroute.Emsg("BreakLink",retc,"unlink symlink target",lnkbuff);
00189               } else {DEBUG("broke link " <<local_path <<"->" <<lnkbuff);}
00190 
00191 // If this is a new-style cache, then we must also remove the pfn file.
00192 // In any case, return the appropriate cache group.
00193 //
00194    lP = lnkbuff+lnklen-1;
00195    if (*lP == XrdOssPath::xChar)
00196       {strcpy(lP+1, ".pfn"); unlink(lnkbuff);
00197        if (statbuff.st_size)
00198           {XrdOssPath::Trim2Base(lP);
00199            XrdOssCache::Adjust(lnkbuff, -statbuff.st_size);
00200           }
00201       } else if (statbuff.st_size)
00202                 XrdOssCache::Adjust(statbuff.st_dev, -statbuff.st_size);
00203 
00204 // All done
00205 //
00206    return retc;
00207 }

Generated on Tue Jul 5 14:46:48 2011 for ROOT_528-00b_version by  doxygen 1.5.1